Add IBatteryStats API to retrieve current charge times.
Also include charge/discharge information in dumpsys.
Change-Id: Ica1b333ad334dc698d4a67da391b378757662f41
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index f05ddde..9e9820f 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -173,6 +173,8 @@
private static final String BLUETOOTH_STATE_COUNT_DATA = "bsc";
private static final String POWER_USE_SUMMARY_DATA = "pws";
private static final String POWER_USE_ITEM_DATA = "pwi";
+ private static final String DISCHARGE_STEP_DATA = "dsd";
+ private static final String CHARGE_STEP_DATA = "csd";
private final StringBuilder mFormatBuilder = new StringBuilder(32);
private final Formatter mFormatter = new Formatter(mFormatBuilder);
@@ -1340,6 +1342,18 @@
public abstract long computeBatteryTimeRemaining(long curTime);
/**
+ * Return the historical number of discharge steps we currently have.
+ */
+ public abstract int getNumDischargeStepDurations();
+
+ /**
+ * Return the array of discharge step durations; the number of valid
+ * items in it is returned by {@link #getNumDischargeStepDurations()}.
+ * These values are in milliseconds.
+ */
+ public abstract long[] getDischargeStepDurationsArray();
+
+ /**
* Compute an approximation for how much time (in microseconds) remains until the battery
* is fully charged. Returns -1 if no time can be computed: either there is not
* enough current data to make a decision, or the battery is currently
@@ -1349,6 +1363,18 @@
*/
public abstract long computeChargeTimeRemaining(long curTime);
+ /**
+ * Return the historical number of charge steps we currently have.
+ */
+ public abstract int getNumChargeStepDurations();
+
+ /**
+ * Return the array of charge step durations; the number of valid
+ * items in it is returned by {@link #getNumChargeStepDurations()}.
+ * These values are in milliseconds.
+ */
+ public abstract long[] getChargeStepDurationsArray();
+
public abstract Map<String, ? extends LongCounter> getWakeupReasonStats();
public abstract Map<String, ? extends Timer> getKernelWakelockStats();
@@ -3120,6 +3146,28 @@
pw.print(suffix);
}
+ private static boolean dumpDurationSteps(PrintWriter pw, String header, long[] steps,
+ int count, boolean checkin) {
+ if (count <= 0) {
+ return false;
+ }
+ if (!checkin) {
+ pw.println(header);
+ }
+ String[] lineArgs = new String[1];
+ for (int i=0; i<count; i++) {
+ if (checkin) {
+ lineArgs[0] = Long.toString(steps[i]);
+ dumpLine(pw, 0 /* uid */, "i" /* category */, header, (Object[])lineArgs);
+ } else {
+ pw.print(" #"); pw.print(i); pw.print(": ");
+ TimeUtils.formatDuration(steps[i], pw);
+ pw.println();
+ }
+ }
+ return true;
+ }
+
public static final int DUMP_UNPLUGGED_ONLY = 1<<0;
public static final int DUMP_CHARGED_ONLY = 1<<1;
public static final int DUMP_HISTORY_ONLY = 1<<2;
@@ -3239,7 +3287,27 @@
}
}
if (didPid) {
- pw.println("");
+ pw.println();
+ }
+ if (dumpDurationSteps(pw, "Discharge step durations:", getDischargeStepDurationsArray(),
+ getNumDischargeStepDurations(), false)) {
+ long timeRemaining = computeBatteryTimeRemaining(SystemClock.elapsedRealtime());
+ if (timeRemaining >= 0) {
+ pw.print(" Estimated discharge time remaining: ");
+ TimeUtils.formatDuration(timeRemaining / 1000, pw);
+ pw.println();
+ }
+ pw.println();
+ }
+ if (dumpDurationSteps(pw, "Charge step durations:", getChargeStepDurationsArray(),
+ getNumChargeStepDurations(), false)) {
+ long timeRemaining = computeChargeTimeRemaining(SystemClock.elapsedRealtime());
+ if (timeRemaining >= 0) {
+ pw.print(" Estimated charge time remaining: ");
+ TimeUtils.formatDuration(timeRemaining / 1000, pw);
+ pw.println();
+ }
+ pw.println();
}
}
@@ -3248,7 +3316,7 @@
pw.println(" System starts: " + getStartCount()
+ ", currently on battery: " + getIsOnBattery());
dumpLocked(context, pw, "", STATS_SINCE_CHARGED, reqUid);
- pw.println("");
+ pw.println();
}
if (!filtering || (flags&DUMP_UNPLUGGED_ONLY) != 0) {
pw.println("Statistics since last unplugged:");
@@ -3352,6 +3420,12 @@
}
}
}
+ if (!filtering) {
+ dumpDurationSteps(pw, DISCHARGE_STEP_DATA, getDischargeStepDurationsArray(),
+ getNumDischargeStepDurations(), true);
+ dumpDurationSteps(pw, CHARGE_STEP_DATA, getChargeStepDurationsArray(),
+ getNumChargeStepDurations(), true);
+ }
if (!filtering || (flags&DUMP_CHARGED_ONLY) != 0) {
dumpCheckinLocked(context, pw, STATS_SINCE_CHARGED, -1);
}
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index fc89b31..1bb577b 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -31,6 +31,14 @@
// Remaining methods are only used in Java.
byte[] getStatistics();
+ // Return the computed amount of time remaining on battery, in milliseconds.
+ // Returns -1 if nothing could be computed.
+ long computeBatteryTimeRemaining();
+
+ // Return the computed amount of time remaining to fully charge, in milliseconds.
+ // Returns -1 if nothing could be computed.
+ long computeChargeTimeRemaining();
+
void addIsolatedUid(int isolatedUid, int appUid);
void removeIsolatedUid(int isolatedUid, int appUid);
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 93d2297..f63fa8a 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -6358,6 +6358,14 @@
return (msPerLevel * mCurrentBatteryLevel) * 1000;
}
+ public int getNumDischargeStepDurations() {
+ return mNumDischargeStepDurations;
+ }
+
+ public long[] getDischargeStepDurationsArray() {
+ return mDischargeStepDurations;
+ }
+
@Override
public long computeChargeTimeRemaining(long curTime) {
if (mOnBattery) {
@@ -6387,6 +6395,14 @@
return (msPerLevel * (100-mCurrentBatteryLevel)) * 1000;
}
+ public int getNumChargeStepDurations() {
+ return mNumChargeStepDurations;
+ }
+
+ public long[] getChargeStepDurationsArray() {
+ return mChargeStepDurations;
+ }
+
long getBatteryUptimeLocked() {
return mOnBatteryTimeBase.getUptime(SystemClock.uptimeMillis() * 1000);
}
@@ -7705,25 +7721,6 @@
pr.println("*** Bluetooth active type #" + i + ":");
mBluetoothStateTimer[i].logState(pr, " ");
}
- StringBuilder sb = new StringBuilder(128);
- if (mNumDischargeStepDurations > 0) {
- pr.println("*** Discharge step durations:");
- for (int i=0; i<mNumDischargeStepDurations; i++) {
- sb.setLength(0);
- sb.append(" #"); sb.append(i); sb.append(": ");
- formatTimeMs(sb, mDischargeStepDurations[i]);
- pr.println(sb.toString());
- }
- }
- if (mNumChargeStepDurations > 0) {
- pr.println("*** Charge step durations:");
- for (int i=0; i<mNumChargeStepDurations; i++) {
- sb.setLength(0);
- sb.append(" #"); sb.append(i); sb.append(": ");
- formatTimeMs(sb, mChargeStepDurations[i]);
- pr.println(sb.toString());
- }
- }
}
super.dumpLocked(context, pw, flags, reqUid, histStart);
}