From e6324f5eec8454f835fe6c8430ddea94436c9656 Mon Sep 17 00:00:00 2001 From: Jason Monk Date: Tue, 23 Feb 2016 12:44:52 -0500 Subject: [PATCH] Support changes in Settings for battery graph Bug: 27205329 Change-Id: I5d15503099144f1c62bafed64ea4c8157e8851ee --- .../src/com/android/settingslib/BatteryInfo.java | 247 +++++++++++++-------- 1 file changed, 150 insertions(+), 97 deletions(-) diff --git a/packages/SettingsLib/src/com/android/settingslib/BatteryInfo.java b/packages/SettingsLib/src/com/android/settingslib/BatteryInfo.java index b16b8ec57c72..6b29e2165c54 100644 --- a/packages/SettingsLib/src/com/android/settingslib/BatteryInfo.java +++ b/packages/SettingsLib/src/com/android/settingslib/BatteryInfo.java @@ -39,121 +39,59 @@ public class BatteryInfo { public String remainingLabel; private BatteryStats mStats; private boolean mCharging; + private long timePeriod; public interface Callback { void onBatteryInfoLoaded(BatteryInfo info); } - public void bindHistory(UsageView view) { - long startWalltime = 0; - long endDateWalltime = 0; - long endWalltime = 0; - long historyStart = 0; - long historyEnd = 0; - byte lastLevel = -1; - long curWalltime = startWalltime; - long lastWallTime = 0; - long lastRealtime = 0; - int lastInteresting = 0; - int pos = 0; - boolean first = true; - if (mStats.startIteratingHistoryLocked()) { - final HistoryItem rec = new HistoryItem(); - while (mStats.getNextHistoryLocked(rec)) { - pos++; - if (first) { - first = false; - historyStart = rec.time; - } - if (rec.cmd == HistoryItem.CMD_CURRENT_TIME - || rec.cmd == HistoryItem.CMD_RESET) { - // If there is a ridiculously large jump in time, then we won't be - // able to create a good chart with that data, so just ignore the - // times we got before and pretend like our data extends back from - // the time we have now. - // Also, if we are getting a time change and we are less than 5 minutes - // since the start of the history real time, then also use this new - // time to compute the base time, since whatever time we had before is - // pretty much just noise. - if (rec.currentTime > (lastWallTime+(180*24*60*60*1000L)) - || rec.time < (historyStart+(5*60*1000L))) { - startWalltime = 0; - } - lastWallTime = rec.currentTime; - lastRealtime = rec.time; - if (startWalltime == 0) { - startWalltime = lastWallTime - (lastRealtime-historyStart); - } - } - if (rec.isDeltaData()) { - if (rec.batteryLevel != lastLevel || pos == 1) { - lastLevel = rec.batteryLevel; - } - lastInteresting = pos; - historyEnd = rec.time; - } + public void bindHistory(final UsageView view, BatteryDataParser... parsers) { + BatteryDataParser parser = new BatteryDataParser() { + SparseIntArray points = new SparseIntArray(); + + @Override + public void onParsingStarted(long startTime, long endTime) { + timePeriod = endTime - startTime - remainingTimeUs / 1000; + view.clearPaths(); + view.configureGraph((int) (endTime - startTime), 100, remainingTimeUs != 0, + mCharging); } - } - mStats.finishIteratingHistoryLocked(); - endDateWalltime = lastWallTime + historyEnd - lastRealtime; - endWalltime = endDateWalltime + (remainingTimeUs / 1000); - int i = 0; - final int N = lastInteresting; - SparseIntArray points = new SparseIntArray(); - view.clearPaths(); - view.configureGraph((int) (endWalltime - startWalltime), 100, remainingTimeUs != 0, - mCharging); - if (endDateWalltime > startWalltime && mStats.startIteratingHistoryLocked()) { - final HistoryItem rec = new HistoryItem(); - while (mStats.getNextHistoryLocked(rec) && i < N) { - if (rec.isDeltaData()) { - curWalltime += rec.time - lastRealtime; - lastRealtime = rec.time; - long x = (curWalltime - startWalltime); - if (x < 0) { - x = 0; - } - points.put((int) x, rec.batteryLevel); - } else { - long lastWalltime = curWalltime; - if (rec.cmd == HistoryItem.CMD_CURRENT_TIME - || rec.cmd == HistoryItem.CMD_RESET) { - if (rec.currentTime >= startWalltime) { - curWalltime = rec.currentTime; - } else { - curWalltime = startWalltime + (rec.time - historyStart); - } - lastRealtime = rec.time; - } + @Override + public void onDataPoint(long time, HistoryItem record) { + points.put((int) time, record.batteryLevel); + } - if (rec.cmd != HistoryItem.CMD_OVERFLOW - && (rec.cmd != HistoryItem.CMD_CURRENT_TIME - || Math.abs(lastWalltime-curWalltime) > (60*60*1000))) { - if (points.size() > 1) { - view.addPath(points); - } - points.clear(); - } + @Override + public void onDataGap() { + if (points.size() > 1) { + view.addPath(points); } - i++; + points.clear(); } + + @Override + public void onParsingDone() { + if (points.size() > 1) { + view.addPath(points); + } + } + }; + BatteryDataParser[] parserList = new BatteryDataParser[parsers.length + 1]; + for (int i = 0; i < parsers.length; i++) { + parserList[i] = parsers[i]; } - if (points.size() > 1) { - view.addPath(points); - } - long timePast = endDateWalltime - startWalltime; + parserList[parsers.length] = parser; + parse(mStats, remainingTimeUs, parserList); final Context context = view.getContext(); String timeString = context.getString(R.string.charge_length_format, - Formatter.formatShortElapsedTime(context, timePast)); + Formatter.formatShortElapsedTime(context, timePeriod)); String remaining = ""; if (remainingTimeUs != 0) { remaining = context.getString(R.string.remaining_length_format, Formatter.formatShortElapsedTime(context, remainingTimeUs / 1000)); } - view.setBottomLabels(new CharSequence[] { timeString, remaining}); - - mStats.finishIteratingHistoryLocked(); + view.setBottomLabels(new CharSequence[]{timeString, remaining}); } public static void getBatteryInfo(final Context context, final Callback callback) { @@ -233,4 +171,119 @@ public class BatteryInfo { } return info; } + + public interface BatteryDataParser { + void onParsingStarted(long startTime, long endTime); + + void onDataPoint(long time, HistoryItem record); + + void onDataGap(); + + void onParsingDone(); + } + + private static void parse(BatteryStats stats, long remainingTimeUs, + BatteryDataParser... parsers) { + long startWalltime = 0; + long endDateWalltime = 0; + long endWalltime = 0; + long historyStart = 0; + long historyEnd = 0; + byte lastLevel = -1; + long curWalltime = startWalltime; + long lastWallTime = 0; + long lastRealtime = 0; + int lastInteresting = 0; + int pos = 0; + boolean first = true; + if (stats.startIteratingHistoryLocked()) { + final HistoryItem rec = new HistoryItem(); + while (stats.getNextHistoryLocked(rec)) { + pos++; + if (first) { + first = false; + historyStart = rec.time; + } + if (rec.cmd == HistoryItem.CMD_CURRENT_TIME + || rec.cmd == HistoryItem.CMD_RESET) { + // If there is a ridiculously large jump in time, then we won't be + // able to create a good chart with that data, so just ignore the + // times we got before and pretend like our data extends back from + // the time we have now. + // Also, if we are getting a time change and we are less than 5 minutes + // since the start of the history real time, then also use this new + // time to compute the base time, since whatever time we had before is + // pretty much just noise. + if (rec.currentTime > (lastWallTime + (180 * 24 * 60 * 60 * 1000L)) + || rec.time < (historyStart + (5 * 60 * 1000L))) { + startWalltime = 0; + } + lastWallTime = rec.currentTime; + lastRealtime = rec.time; + if (startWalltime == 0) { + startWalltime = lastWallTime - (lastRealtime - historyStart); + } + } + if (rec.isDeltaData()) { + if (rec.batteryLevel != lastLevel || pos == 1) { + lastLevel = rec.batteryLevel; + } + lastInteresting = pos; + historyEnd = rec.time; + } + } + } + stats.finishIteratingHistoryLocked(); + endDateWalltime = lastWallTime + historyEnd - lastRealtime; + endWalltime = endDateWalltime + (remainingTimeUs / 1000); + + int i = 0; + final int N = lastInteresting; + + for (int j = 0; j < parsers.length; j++) { + parsers[j].onParsingStarted(startWalltime, endWalltime); + } + if (endDateWalltime > startWalltime && stats.startIteratingHistoryLocked()) { + final HistoryItem rec = new HistoryItem(); + while (stats.getNextHistoryLocked(rec) && i < N) { + if (rec.isDeltaData()) { + curWalltime += rec.time - lastRealtime; + lastRealtime = rec.time; + long x = (curWalltime - startWalltime); + if (x < 0) { + x = 0; + } + for (int j = 0; j < parsers.length; j++) { + parsers[j].onDataPoint(x, rec); + } + } else { + long lastWalltime = curWalltime; + if (rec.cmd == HistoryItem.CMD_CURRENT_TIME + || rec.cmd == HistoryItem.CMD_RESET) { + if (rec.currentTime >= startWalltime) { + curWalltime = rec.currentTime; + } else { + curWalltime = startWalltime + (rec.time - historyStart); + } + lastRealtime = rec.time; + } + + if (rec.cmd != HistoryItem.CMD_OVERFLOW + && (rec.cmd != HistoryItem.CMD_CURRENT_TIME + || Math.abs(lastWalltime - curWalltime) > (60 * 60 * 1000))) { + for (int j = 0; j < parsers.length; j++) { + parsers[j].onDataGap(); + } + } + } + i++; + } + } + + stats.finishIteratingHistoryLocked(); + + for (int j = 0; j < parsers.length; j++) { + parsers[j].onParsingDone(); + } + } } -- 2.11.0