Adding batterystats history to proto dump.
It will only print out a dump for userdebug or eng builds.
Bug: 77727638
Test: flash device and check output of incident proto and
'dumpsys batterystats -c --history'
Merged-In: Ib74d4c664f23a61e6fc33f700ba6a3c6fad32c74
Change-Id: Ia0c993d1281cc350d93f9c13f5540b349a4bfb84
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 0b4b921..619ec23 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -21,6 +21,7 @@
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.server.ServerProtoEnums;
+import android.service.batterystats.BatteryStatsServiceDumpHistoryProto;
import android.service.batterystats.BatteryStatsServiceDumpProto;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
@@ -6030,51 +6031,51 @@
}
}
- static void printBitDescriptions(PrintWriter pw, int oldval, int newval, HistoryTag wakelockTag,
- BitDescription[] descriptions, boolean longNames) {
+ static void printBitDescriptions(StringBuilder sb, int oldval, int newval,
+ HistoryTag wakelockTag, BitDescription[] descriptions, boolean longNames) {
int diff = oldval ^ newval;
if (diff == 0) return;
boolean didWake = false;
for (int i=0; i<descriptions.length; i++) {
BitDescription bd = descriptions[i];
if ((diff&bd.mask) != 0) {
- pw.print(longNames ? " " : ",");
+ sb.append(longNames ? " " : ",");
if (bd.shift < 0) {
- pw.print((newval&bd.mask) != 0 ? "+" : "-");
- pw.print(longNames ? bd.name : bd.shortName);
+ sb.append((newval & bd.mask) != 0 ? "+" : "-");
+ sb.append(longNames ? bd.name : bd.shortName);
if (bd.mask == HistoryItem.STATE_WAKE_LOCK_FLAG && wakelockTag != null) {
didWake = true;
- pw.print("=");
+ sb.append("=");
if (longNames) {
- UserHandle.formatUid(pw, wakelockTag.uid);
- pw.print(":\"");
- pw.print(wakelockTag.string);
- pw.print("\"");
+ UserHandle.formatUid(sb, wakelockTag.uid);
+ sb.append(":\"");
+ sb.append(wakelockTag.string);
+ sb.append("\"");
} else {
- pw.print(wakelockTag.poolIdx);
+ sb.append(wakelockTag.poolIdx);
}
}
} else {
- pw.print(longNames ? bd.name : bd.shortName);
- pw.print("=");
+ sb.append(longNames ? bd.name : bd.shortName);
+ sb.append("=");
int val = (newval&bd.mask)>>bd.shift;
if (bd.values != null && val >= 0 && val < bd.values.length) {
- pw.print(longNames? bd.values[val] : bd.shortValues[val]);
+ sb.append(longNames ? bd.values[val] : bd.shortValues[val]);
} else {
- pw.print(val);
+ sb.append(val);
}
}
}
}
if (!didWake && wakelockTag != null) {
- pw.print(longNames ? " wake_lock=" : ",w=");
+ sb.append(longNames ? " wake_lock=" : ",w=");
if (longNames) {
- UserHandle.formatUid(pw, wakelockTag.uid);
- pw.print(":\"");
- pw.print(wakelockTag.string);
- pw.print("\"");
+ UserHandle.formatUid(sb, wakelockTag.uid);
+ sb.append(":\"");
+ sb.append(wakelockTag.string);
+ sb.append("\"");
} else {
- pw.print(wakelockTag.poolIdx);
+ sb.append(wakelockTag.poolIdx);
}
}
}
@@ -6108,339 +6109,360 @@
public void printNextItem(PrintWriter pw, HistoryItem rec, long baseTime, boolean checkin,
boolean verbose) {
+ pw.print(printNextItem(rec, baseTime, checkin, verbose));
+ }
+
+ /** Print the next history item to proto. */
+ public void printNextItem(ProtoOutputStream proto, HistoryItem rec, long baseTime,
+ boolean verbose) {
+ String item = printNextItem(rec, baseTime, true, verbose);
+ for (String line : item.split("\n")) {
+ proto.write(BatteryStatsServiceDumpHistoryProto.CSV_LINES, line);
+ }
+ }
+
+ private String printNextItem(HistoryItem rec, long baseTime, boolean checkin,
+ boolean verbose) {
+ StringBuilder item = new StringBuilder();
if (!checkin) {
- pw.print(" ");
- TimeUtils.formatDuration(rec.time - baseTime, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN);
- pw.print(" (");
- pw.print(rec.numReadInts);
- pw.print(") ");
+ item.append(" ");
+ TimeUtils.formatDuration(
+ rec.time - baseTime, item, TimeUtils.HUNDRED_DAY_FIELD_LEN);
+ item.append(" (");
+ item.append(rec.numReadInts);
+ item.append(") ");
} else {
- pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
- pw.print(HISTORY_DATA); pw.print(',');
+ item.append(BATTERY_STATS_CHECKIN_VERSION); item.append(',');
+ item.append(HISTORY_DATA); item.append(',');
if (lastTime < 0) {
- pw.print(rec.time - baseTime);
+ item.append(rec.time - baseTime);
} else {
- pw.print(rec.time - lastTime);
+ item.append(rec.time - lastTime);
}
lastTime = rec.time;
}
if (rec.cmd == HistoryItem.CMD_START) {
if (checkin) {
- pw.print(":");
+ item.append(":");
}
- pw.println("START");
+ item.append("START\n");
reset();
} else if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
|| rec.cmd == HistoryItem.CMD_RESET) {
if (checkin) {
- pw.print(":");
+ item.append(":");
}
if (rec.cmd == HistoryItem.CMD_RESET) {
- pw.print("RESET:");
+ item.append("RESET:");
reset();
}
- pw.print("TIME:");
+ item.append("TIME:");
if (checkin) {
- pw.println(rec.currentTime);
+ item.append(rec.currentTime);
+ item.append("\n");
} else {
- pw.print(" ");
- pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss",
+ item.append(" ");
+ item.append(DateFormat.format("yyyy-MM-dd-HH-mm-ss",
rec.currentTime).toString());
+ item.append("\n");
}
} else if (rec.cmd == HistoryItem.CMD_SHUTDOWN) {
if (checkin) {
- pw.print(":");
+ item.append(":");
}
- pw.println("SHUTDOWN");
+ item.append("SHUTDOWN\n");
} else if (rec.cmd == HistoryItem.CMD_OVERFLOW) {
if (checkin) {
- pw.print(":");
+ item.append(":");
}
- pw.println("*OVERFLOW*");
+ item.append("*OVERFLOW*\n");
} else {
if (!checkin) {
- if (rec.batteryLevel < 10) pw.print("00");
- else if (rec.batteryLevel < 100) pw.print("0");
- pw.print(rec.batteryLevel);
+ if (rec.batteryLevel < 10) item.append("00");
+ else if (rec.batteryLevel < 100) item.append("0");
+ item.append(rec.batteryLevel);
if (verbose) {
- pw.print(" ");
+ item.append(" ");
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 (rec.states < 0x10) item.append("0000000");
+ else if (rec.states < 0x100) item.append("000000");
+ else if (rec.states < 0x1000) item.append("00000");
+ else if (rec.states < 0x10000) item.append("0000");
+ else if (rec.states < 0x100000) item.append("000");
+ else if (rec.states < 0x1000000) item.append("00");
+ else if (rec.states < 0x10000000) item.append("0");
+ item.append(Integer.toHexString(rec.states));
}
} else {
if (oldLevel != rec.batteryLevel) {
oldLevel = rec.batteryLevel;
- pw.print(",Bl="); pw.print(rec.batteryLevel);
+ item.append(",Bl="); item.append(rec.batteryLevel);
}
}
if (oldStatus != rec.batteryStatus) {
oldStatus = rec.batteryStatus;
- pw.print(checkin ? ",Bs=" : " status=");
+ item.append(checkin ? ",Bs=" : " status=");
switch (oldStatus) {
case BatteryManager.BATTERY_STATUS_UNKNOWN:
- pw.print(checkin ? "?" : "unknown");
+ item.append(checkin ? "?" : "unknown");
break;
case BatteryManager.BATTERY_STATUS_CHARGING:
- pw.print(checkin ? "c" : "charging");
+ item.append(checkin ? "c" : "charging");
break;
case BatteryManager.BATTERY_STATUS_DISCHARGING:
- pw.print(checkin ? "d" : "discharging");
+ item.append(checkin ? "d" : "discharging");
break;
case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
- pw.print(checkin ? "n" : "not-charging");
+ item.append(checkin ? "n" : "not-charging");
break;
case BatteryManager.BATTERY_STATUS_FULL:
- pw.print(checkin ? "f" : "full");
+ item.append(checkin ? "f" : "full");
break;
default:
- pw.print(oldStatus);
+ item.append(oldStatus);
break;
}
}
if (oldHealth != rec.batteryHealth) {
oldHealth = rec.batteryHealth;
- pw.print(checkin ? ",Bh=" : " health=");
+ item.append(checkin ? ",Bh=" : " health=");
switch (oldHealth) {
case BatteryManager.BATTERY_HEALTH_UNKNOWN:
- pw.print(checkin ? "?" : "unknown");
+ item.append(checkin ? "?" : "unknown");
break;
case BatteryManager.BATTERY_HEALTH_GOOD:
- pw.print(checkin ? "g" : "good");
+ item.append(checkin ? "g" : "good");
break;
case BatteryManager.BATTERY_HEALTH_OVERHEAT:
- pw.print(checkin ? "h" : "overheat");
+ item.append(checkin ? "h" : "overheat");
break;
case BatteryManager.BATTERY_HEALTH_DEAD:
- pw.print(checkin ? "d" : "dead");
+ item.append(checkin ? "d" : "dead");
break;
case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE:
- pw.print(checkin ? "v" : "over-voltage");
+ item.append(checkin ? "v" : "over-voltage");
break;
case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE:
- pw.print(checkin ? "f" : "failure");
+ item.append(checkin ? "f" : "failure");
break;
case BatteryManager.BATTERY_HEALTH_COLD:
- pw.print(checkin ? "c" : "cold");
+ item.append(checkin ? "c" : "cold");
break;
default:
- pw.print(oldHealth);
+ item.append(oldHealth);
break;
}
}
if (oldPlug != rec.batteryPlugType) {
oldPlug = rec.batteryPlugType;
- pw.print(checkin ? ",Bp=" : " plug=");
+ item.append(checkin ? ",Bp=" : " plug=");
switch (oldPlug) {
case 0:
- pw.print(checkin ? "n" : "none");
+ item.append(checkin ? "n" : "none");
break;
case BatteryManager.BATTERY_PLUGGED_AC:
- pw.print(checkin ? "a" : "ac");
+ item.append(checkin ? "a" : "ac");
break;
case BatteryManager.BATTERY_PLUGGED_USB:
- pw.print(checkin ? "u" : "usb");
+ item.append(checkin ? "u" : "usb");
break;
case BatteryManager.BATTERY_PLUGGED_WIRELESS:
- pw.print(checkin ? "w" : "wireless");
+ item.append(checkin ? "w" : "wireless");
break;
default:
- pw.print(oldPlug);
+ item.append(oldPlug);
break;
}
}
if (oldTemp != rec.batteryTemperature) {
oldTemp = rec.batteryTemperature;
- pw.print(checkin ? ",Bt=" : " temp=");
- pw.print(oldTemp);
+ item.append(checkin ? ",Bt=" : " temp=");
+ item.append(oldTemp);
}
if (oldVolt != rec.batteryVoltage) {
oldVolt = rec.batteryVoltage;
- pw.print(checkin ? ",Bv=" : " volt=");
- pw.print(oldVolt);
+ item.append(checkin ? ",Bv=" : " volt=");
+ item.append(oldVolt);
}
final int chargeMAh = rec.batteryChargeUAh / 1000;
if (oldChargeMAh != chargeMAh) {
oldChargeMAh = chargeMAh;
- pw.print(checkin ? ",Bcc=" : " charge=");
- pw.print(oldChargeMAh);
+ item.append(checkin ? ",Bcc=" : " charge=");
+ item.append(oldChargeMAh);
}
- printBitDescriptions(pw, oldState, rec.states, rec.wakelockTag,
+ printBitDescriptions(item, oldState, rec.states, rec.wakelockTag,
HISTORY_STATE_DESCRIPTIONS, !checkin);
- printBitDescriptions(pw, oldState2, rec.states2, null,
+ printBitDescriptions(item, oldState2, rec.states2, null,
HISTORY_STATE2_DESCRIPTIONS, !checkin);
if (rec.wakeReasonTag != null) {
if (checkin) {
- pw.print(",wr=");
- pw.print(rec.wakeReasonTag.poolIdx);
+ item.append(",wr=");
+ item.append(rec.wakeReasonTag.poolIdx);
} else {
- pw.print(" wake_reason=");
- pw.print(rec.wakeReasonTag.uid);
- pw.print(":\"");
- pw.print(rec.wakeReasonTag.string);
- pw.print("\"");
+ item.append(" wake_reason=");
+ item.append(rec.wakeReasonTag.uid);
+ item.append(":\"");
+ item.append(rec.wakeReasonTag.string);
+ item.append("\"");
}
}
if (rec.eventCode != HistoryItem.EVENT_NONE) {
- pw.print(checkin ? "," : " ");
+ item.append(checkin ? "," : " ");
if ((rec.eventCode&HistoryItem.EVENT_FLAG_START) != 0) {
- pw.print("+");
+ item.append("+");
} else if ((rec.eventCode&HistoryItem.EVENT_FLAG_FINISH) != 0) {
- pw.print("-");
+ item.append("-");
}
String[] eventNames = checkin ? HISTORY_EVENT_CHECKIN_NAMES
: HISTORY_EVENT_NAMES;
int idx = rec.eventCode & ~(HistoryItem.EVENT_FLAG_START
| HistoryItem.EVENT_FLAG_FINISH);
if (idx >= 0 && idx < eventNames.length) {
- pw.print(eventNames[idx]);
+ item.append(eventNames[idx]);
} else {
- pw.print(checkin ? "Ev" : "event");
- pw.print(idx);
+ item.append(checkin ? "Ev" : "event");
+ item.append(idx);
}
- pw.print("=");
+ item.append("=");
if (checkin) {
- pw.print(rec.eventTag.poolIdx);
+ item.append(rec.eventTag.poolIdx);
} else {
- pw.append(HISTORY_EVENT_INT_FORMATTERS[idx]
+ item.append(HISTORY_EVENT_INT_FORMATTERS[idx]
.applyAsString(rec.eventTag.uid));
- pw.print(":\"");
- pw.print(rec.eventTag.string);
- pw.print("\"");
+ item.append(":\"");
+ item.append(rec.eventTag.string);
+ item.append("\"");
}
}
- pw.println();
+ item.append("\n");
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");
+ item.append(" Details: cpu=");
+ item.append(rec.stepDetails.userTime);
+ item.append("u+");
+ item.append(rec.stepDetails.systemTime);
+ item.append("s");
if (rec.stepDetails.appCpuUid1 >= 0) {
- pw.print(" (");
- printStepCpuUidDetails(pw, rec.stepDetails.appCpuUid1,
+ item.append(" (");
+ printStepCpuUidDetails(item, rec.stepDetails.appCpuUid1,
rec.stepDetails.appCpuUTime1, rec.stepDetails.appCpuSTime1);
if (rec.stepDetails.appCpuUid2 >= 0) {
- pw.print(", ");
- printStepCpuUidDetails(pw, rec.stepDetails.appCpuUid2,
+ item.append(", ");
+ printStepCpuUidDetails(item, rec.stepDetails.appCpuUid2,
rec.stepDetails.appCpuUTime2, rec.stepDetails.appCpuSTime2);
}
if (rec.stepDetails.appCpuUid3 >= 0) {
- pw.print(", ");
- printStepCpuUidDetails(pw, rec.stepDetails.appCpuUid3,
+ item.append(", ");
+ printStepCpuUidDetails(item, rec.stepDetails.appCpuUid3,
rec.stepDetails.appCpuUTime3, rec.stepDetails.appCpuSTime3);
}
- pw.print(')');
+ item.append(')');
}
- 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");
+ item.append("\n");
+ item.append(" /proc/stat=");
+ item.append(rec.stepDetails.statUserTime);
+ item.append(" usr, ");
+ item.append(rec.stepDetails.statSystemTime);
+ item.append(" sys, ");
+ item.append(rec.stepDetails.statIOWaitTime);
+ item.append(" io, ");
+ item.append(rec.stepDetails.statIrqTime);
+ item.append(" irq, ");
+ item.append(rec.stepDetails.statSoftIrqTime);
+ item.append(" sirq, ");
+ item.append(rec.stepDetails.statIdlTime);
+ item.append(" 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(" (");
+ item.append(" (");
float perc = ((float)totalRun) / ((float)total) * 100;
- pw.print(String.format("%.1f%%", perc));
- pw.print(" of ");
+ item.append(String.format("%.1f%%", perc));
+ item.append(" of ");
StringBuilder sb = new StringBuilder(64);
formatTimeMsNoSpace(sb, total*10);
- pw.print(sb);
- pw.print(")");
+ item.append(sb);
+ item.append(")");
}
- pw.print(", PlatformIdleStat ");
- pw.print(rec.stepDetails.statPlatformIdleState);
- pw.println();
+ item.append(", PlatformIdleStat ");
+ item.append(rec.stepDetails.statPlatformIdleState);
+ item.append("\n");
- pw.print(", SubsystemPowerState ");
- pw.print(rec.stepDetails.statSubsystemPowerState);
- pw.println();
+ item.append(", SubsystemPowerState ");
+ item.append(rec.stepDetails.statSubsystemPowerState);
+ item.append("\n");
} 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);
+ item.append(BATTERY_STATS_CHECKIN_VERSION); item.append(',');
+ item.append(HISTORY_DATA); item.append(",0,Dcpu=");
+ item.append(rec.stepDetails.userTime);
+ item.append(":");
+ item.append(rec.stepDetails.systemTime);
if (rec.stepDetails.appCpuUid1 >= 0) {
- printStepCpuUidCheckinDetails(pw, rec.stepDetails.appCpuUid1,
+ printStepCpuUidCheckinDetails(item, rec.stepDetails.appCpuUid1,
rec.stepDetails.appCpuUTime1, rec.stepDetails.appCpuSTime1);
if (rec.stepDetails.appCpuUid2 >= 0) {
- printStepCpuUidCheckinDetails(pw, rec.stepDetails.appCpuUid2,
+ printStepCpuUidCheckinDetails(item, rec.stepDetails.appCpuUid2,
rec.stepDetails.appCpuUTime2, rec.stepDetails.appCpuSTime2);
}
if (rec.stepDetails.appCpuUid3 >= 0) {
- printStepCpuUidCheckinDetails(pw, rec.stepDetails.appCpuUid3,
+ printStepCpuUidCheckinDetails(item, 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.print(',');
+ item.append("\n");
+ item.append(BATTERY_STATS_CHECKIN_VERSION); item.append(',');
+ item.append(HISTORY_DATA); item.append(",0,Dpst=");
+ item.append(rec.stepDetails.statUserTime);
+ item.append(',');
+ item.append(rec.stepDetails.statSystemTime);
+ item.append(',');
+ item.append(rec.stepDetails.statIOWaitTime);
+ item.append(',');
+ item.append(rec.stepDetails.statIrqTime);
+ item.append(',');
+ item.append(rec.stepDetails.statSoftIrqTime);
+ item.append(',');
+ item.append(rec.stepDetails.statIdlTime);
+ item.append(',');
if (rec.stepDetails.statPlatformIdleState != null) {
- pw.print(rec.stepDetails.statPlatformIdleState);
+ item.append(rec.stepDetails.statPlatformIdleState);
if (rec.stepDetails.statSubsystemPowerState != null) {
- pw.print(',');
+ item.append(',');
}
}
if (rec.stepDetails.statSubsystemPowerState != null) {
- pw.print(rec.stepDetails.statSubsystemPowerState);
+ item.append(rec.stepDetails.statSubsystemPowerState);
}
- pw.println();
+ item.append("\n");
}
}
oldState = rec.states;
oldState2 = rec.states2;
}
+
+ return item.toString();
}
- 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 printStepCpuUidDetails(StringBuilder sb, int uid, int utime, int stime) {
+ UserHandle.formatUid(sb, uid);
+ sb.append("=");
+ sb.append(utime);
+ sb.append("u+");
+ sb.append(stime);
+ sb.append("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 printStepCpuUidCheckinDetails(StringBuilder sb, int uid, int utime,
+ int stime) {
+ sb.append('/');
+ sb.append(uid);
+ sb.append(":");
+ sb.append(utime);
+ sb.append(":");
+ sb.append(stime);
}
}
@@ -7046,21 +7068,30 @@
}
}
- /** Dump #STATS_SINCE_CHARGED batterystats data to a proto. @hide */
+ /**
+ * Dump #STATS_SINCE_CHARGED batterystats data to a proto. If the flags include
+ * DUMP_INCLUDE_HISTORY or DUMP_HISTORY_ONLY, only the history will be dumped.
+ * @hide
+ */
public void dumpProtoLocked(Context context, FileDescriptor fd, List<ApplicationInfo> apps,
- int flags) {
+ int flags, long histStart) {
final ProtoOutputStream proto = new ProtoOutputStream(fd);
- final long bToken = proto.start(BatteryStatsServiceDumpProto.BATTERYSTATS);
prepareForDumpLocked();
+ if ((flags & (DUMP_INCLUDE_HISTORY | DUMP_HISTORY_ONLY)) != 0) {
+ dumpProtoHistoryLocked(proto, flags, histStart);
+ proto.flush();
+ return;
+ }
+
+ final long bToken = proto.start(BatteryStatsServiceDumpProto.BATTERYSTATS);
+
proto.write(BatteryStatsProto.REPORT_VERSION, CHECKIN_VERSION);
proto.write(BatteryStatsProto.PARCEL_VERSION, getParcelVersion());
proto.write(BatteryStatsProto.START_PLATFORM_VERSION, getStartPlatformVersion());
proto.write(BatteryStatsProto.END_PLATFORM_VERSION, getEndPlatformVersion());
- // History intentionally not included in proto dump.
-
- if ((flags & (DUMP_HISTORY_ONLY | DUMP_DAILY_ONLY)) == 0) {
+ if ((flags & DUMP_DAILY_ONLY) == 0) {
final BatteryStatsHelper helper = new BatteryStatsHelper(context, false,
(flags & DUMP_DEVICE_WIFI_ONLY) != 0);
helper.create(this);
@@ -7530,6 +7561,108 @@
}
}
+ private void dumpProtoHistoryLocked(ProtoOutputStream proto, int flags, long histStart) {
+ if (!startIteratingHistoryLocked()) {
+ return;
+ }
+
+ proto.write(BatteryStatsServiceDumpHistoryProto.REPORT_VERSION, CHECKIN_VERSION);
+ proto.write(BatteryStatsServiceDumpHistoryProto.PARCEL_VERSION, getParcelVersion());
+ proto.write(BatteryStatsServiceDumpHistoryProto.START_PLATFORM_VERSION,
+ getStartPlatformVersion());
+ proto.write(BatteryStatsServiceDumpHistoryProto.END_PLATFORM_VERSION,
+ getEndPlatformVersion());
+ try {
+ long token;
+ // History string pool (HISTORY_STRING_POOL)
+ for (int i = 0; i < getHistoryStringPoolSize(); ++i) {
+ token = proto.start(BatteryStatsServiceDumpHistoryProto.KEYS);
+ proto.write(BatteryStatsServiceDumpHistoryProto.Key.INDEX, i);
+ proto.write(BatteryStatsServiceDumpHistoryProto.Key.UID, getHistoryTagPoolUid(i));
+ proto.write(BatteryStatsServiceDumpHistoryProto.Key.TAG,
+ getHistoryTagPoolString(i));
+ proto.end(token);
+ }
+
+ // History data (HISTORY_DATA)
+ final HistoryPrinter hprinter = new HistoryPrinter();
+ final HistoryItem rec = new HistoryItem();
+ long lastTime = -1;
+ long baseTime = -1;
+ boolean printed = false;
+ HistoryEventTracker tracker = null;
+ while (getNextHistoryLocked(rec)) {
+ lastTime = rec.time;
+ if (baseTime < 0) {
+ baseTime = lastTime;
+ }
+ if (rec.time >= histStart) {
+ if (histStart >= 0 && !printed) {
+ if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
+ || rec.cmd == HistoryItem.CMD_RESET
+ || rec.cmd == HistoryItem.CMD_START
+ || rec.cmd == HistoryItem.CMD_SHUTDOWN) {
+ printed = true;
+ hprinter.printNextItem(proto, rec, baseTime,
+ (flags & DUMP_VERBOSE) != 0);
+ rec.cmd = HistoryItem.CMD_UPDATE;
+ } else if (rec.currentTime != 0) {
+ printed = true;
+ byte cmd = rec.cmd;
+ rec.cmd = HistoryItem.CMD_CURRENT_TIME;
+ hprinter.printNextItem(proto, rec, baseTime,
+ (flags & DUMP_VERBOSE) != 0);
+ rec.cmd = cmd;
+ }
+ if (tracker != null) {
+ if (rec.cmd != HistoryItem.CMD_UPDATE) {
+ hprinter.printNextItem(proto, rec, baseTime,
+ (flags & DUMP_VERBOSE) != 0);
+ rec.cmd = HistoryItem.CMD_UPDATE;
+ }
+ int oldEventCode = rec.eventCode;
+ HistoryTag oldEventTag = rec.eventTag;
+ rec.eventTag = new HistoryTag();
+ for (int i = 0; i < HistoryItem.EVENT_COUNT; i++) {
+ HashMap<String, SparseIntArray> active =
+ tracker.getStateForEvent(i);
+ if (active == null) {
+ continue;
+ }
+ for (HashMap.Entry<String, SparseIntArray> ent
+ : active.entrySet()) {
+ SparseIntArray uids = ent.getValue();
+ for (int j = 0; j < uids.size(); j++) {
+ rec.eventCode = i;
+ rec.eventTag.string = ent.getKey();
+ rec.eventTag.uid = uids.keyAt(j);
+ rec.eventTag.poolIdx = uids.valueAt(j);
+ hprinter.printNextItem(proto, rec, baseTime,
+ (flags & DUMP_VERBOSE) != 0);
+ rec.wakeReasonTag = null;
+ rec.wakelockTag = null;
+ }
+ }
+ }
+ rec.eventCode = oldEventCode;
+ rec.eventTag = oldEventTag;
+ tracker = null;
+ }
+ }
+ hprinter.printNextItem(proto, rec, baseTime,
+ (flags & DUMP_VERBOSE) != 0);
+ }
+ }
+ if (histStart >= 0) {
+ commitCurrentHistoryBatchLocked();
+ proto.write(BatteryStatsServiceDumpHistoryProto.CSV_LINES,
+ "NEXT: " + (lastTime + 1));
+ }
+ } finally {
+ finishIteratingHistoryLocked();
+ }
+ }
+
private void dumpProtoSystemLocked(ProtoOutputStream proto, BatteryStatsHelper helper) {
final long sToken = proto.start(BatteryStatsProto.SYSTEM);
final long rawUptimeUs = SystemClock.uptimeMillis() * 1000;
diff --git a/core/java/android/util/TimeUtils.java b/core/java/android/util/TimeUtils.java
index 84ae20b..05b613c 100644
--- a/core/java/android/util/TimeUtils.java
+++ b/core/java/android/util/TimeUtils.java
@@ -240,6 +240,14 @@
}
/** @hide Just for debugging; not internationalized. */
+ public static void formatDuration(long duration, StringBuilder builder, int fieldLen) {
+ synchronized (sFormatSync) {
+ int len = formatDurationLocked(duration, fieldLen);
+ builder.append(sFormatStr, 0, len);
+ }
+ }
+
+ /** @hide Just for debugging; not internationalized. */
public static void formatDuration(long duration, PrintWriter pw, int fieldLen) {
synchronized (sFormatSync) {
int len = formatDurationLocked(duration, fieldLen);