Improve battery chart, fuel gauge now shows time since charged.

Switch default stats to new time since charged.  Update to follow
API changes.  Improve the battery history chart.

Change-Id: I7de4f09ae5638ec3a034745244082e51b1369929
This commit is contained in:
Dianne Hackborn
2010-06-14 17:18:42 -07:00
parent ea38e67853
commit d342c0685d
2 changed files with 140 additions and 39 deletions

View File

@@ -23,20 +23,28 @@ import android.content.res.ColorStateList;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.os.BatteryStats; import android.os.BatteryStats;
import android.os.SystemClock; import android.os.SystemClock;
import android.os.BatteryStats.BatteryHistoryRecord; import android.os.BatteryStats.HistoryItem;
import android.text.TextPaint; import android.text.TextPaint;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View; import android.view.View;
public class BatteryHistoryChart extends View { public class BatteryHistoryChart extends View {
private static final int SANS = 1; static final int SANS = 1;
private static final int SERIF = 2; static final int SERIF = 2;
private static final int MONOSPACE = 3; static final int MONOSPACE = 3;
final Paint mBatteryPaint = new Paint(Paint.ANTI_ALIAS_FLAG); static final int BATTERY_WARN = 29;
static final int BATTERY_CRITICAL = 14;
final Paint mBatteryBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
final Paint mBatteryGoodPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
final Paint mBatteryWarnPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
final Paint mBatteryCriticalPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
final TextPaint mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); final TextPaint mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
int mFontSize; int mFontSize;
@@ -55,10 +63,26 @@ public class BatteryHistoryChart extends View {
int mBatLow; int mBatLow;
int mBatHigh; int mBatHigh;
final Path mBatLevelPath = new Path();
int[] mBatLevelX;
int[] mBatLevelY;
byte[] mBatLevelValue;
int mNumBatLevel;
public BatteryHistoryChart(Context context, AttributeSet attrs) { public BatteryHistoryChart(Context context, AttributeSet attrs) {
super(context, attrs); super(context, attrs);
mBatteryPaint.setARGB(255, 255, 128, 128); mBatteryBackgroundPaint.setARGB(255, 128, 128, 128);
mBatteryBackgroundPaint.setStyle(Paint.Style.FILL);
mBatteryGoodPaint.setARGB(128, 0, 255, 0);
int lineWidth = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
2, getResources().getDisplayMetrics());
if (lineWidth <= 0) lineWidth = 1;
mBatteryGoodPaint.setStrokeWidth(lineWidth);
mBatteryWarnPaint.setARGB(128, 255, 255, 0);
mBatteryWarnPaint.setStrokeWidth(lineWidth);
mBatteryCriticalPaint.setARGB(192, 255, 0, 0);
mBatteryCriticalPaint.setStrokeWidth(lineWidth);
mTextPaint.density = getResources().getDisplayMetrics().density; mTextPaint.density = getResources().getDisplayMetrics().density;
mTextPaint.setCompatibilityScaling( mTextPaint.setCompatibilityScaling(
@@ -199,30 +223,33 @@ public class BatteryHistoryChart extends View {
mStats = stats; mStats = stats;
long uSecTime = mStats.computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, long uSecTime = mStats.computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000,
BatteryStats.STATS_UNPLUGGED); BatteryStats.STATS_SINCE_CHARGED);
mStatsPeriod = uSecTime; mStatsPeriod = uSecTime;
String durationString = Utils.formatElapsedTime(getContext(), mStatsPeriod / 1000); String durationString = Utils.formatElapsedTime(getContext(), mStatsPeriod / 1000);
mDurationString = getContext().getString(R.string.battery_stats_on_battery, mDurationString = getContext().getString(R.string.battery_stats_on_battery,
durationString); durationString);
BatteryStats.BatteryHistoryRecord rec = stats.getHistory(); BatteryStats.HistoryItem rec = stats.getHistory();
if (rec != null) { if (rec != null) {
mHistStart = rec.time; mHistStart = rec.time;
mBatLow = mBatHigh = rec.batteryLevel; mBatLow = mBatHigh = rec.batteryLevel;
} }
int pos = 0; int pos = 0;
int lastUnplugged = 0; int lastInteresting = 0;
byte lastLevel = -1;
mBatLow = 0; mBatLow = 0;
mBatHigh = 100; mBatHigh = 100;
while (rec != null) { while (rec != null) {
pos++; pos++;
if ((rec.states&BatteryHistoryRecord.STATE_BATTERY_PLUGGED_FLAG) == 0) { if (rec.cmd == HistoryItem.CMD_UPDATE && (rec.batteryLevel != lastLevel
lastUnplugged = pos; || pos == 1)) {
lastLevel = rec.batteryLevel;
lastInteresting = pos;
mHistEnd = rec.time; mHistEnd = rec.time;
} }
rec = rec.next; rec = rec.next;
} }
mNumHist = lastUnplugged; mNumHist = lastInteresting;
if (mHistEnd <= mHistStart) mHistEnd = mHistStart+1; if (mHistEnd <= mHistStart) mHistEnd = mHistStart+1;
} }
@@ -238,6 +265,83 @@ public class BatteryHistoryChart extends View {
@Override @Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) { protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh); super.onSizeChanged(w, h, oldw, oldh);
mBatLevelPath.reset();
mBatLevelX = new int[w+5];
mBatLevelY = new int[w+5];
mBatLevelValue = new byte[w+5];
mNumBatLevel = 0;
final long timeStart = mHistStart;
final long timeChange = mHistEnd-mHistStart;
final int batLow = mBatLow;
final int batChange = mBatHigh-mBatLow;
BatteryStats.HistoryItem rec = mStats.getHistory();
int x = 0, y = 0, lastX = -1, lastY = -1, lastBatX = -1, lastBatY = -1;
byte lastBatValue = 0;
int i = 0, num = 0;
boolean first = true;
final int N = mNumHist;
while (rec != null && i < N) {
if (rec.cmd == BatteryStats.HistoryItem.CMD_UPDATE) {
x = (int)(((rec.time-timeStart)*w)/timeChange);
y = h-1 - ((rec.batteryLevel-batLow)*(h-3))/batChange;
if (first) {
first = false;
mBatLevelPath.moveTo(x, y);
mBatLevelX[mNumBatLevel] = x;
mBatLevelY[mNumBatLevel] = y;
mBatLevelValue[mNumBatLevel] = lastBatValue = rec.batteryLevel;
mNumBatLevel++;
lastX = lastBatX = x;
lastY = lastBatY = y;
} else {
if (lastX != x) {
// We have moved by at least a pixel.
if (lastY == y) {
// Battery level is still the same; don't plot,
// but remember it.
lastBatX = x;
lastBatY = y;
} else {
if (lastBatX >= 0) {
// Level stayed the same up to here; put in line.
mBatLevelPath.lineTo(lastBatX, lastBatY);
mBatLevelX[mNumBatLevel] = lastBatX;
mBatLevelY[mNumBatLevel] = lastBatY;
mBatLevelValue[mNumBatLevel] = lastBatValue;
mNumBatLevel++;
num++;
}
mBatLevelPath.lineTo(x, y);
mBatLevelX[mNumBatLevel] = x;
mBatLevelY[mNumBatLevel] = y;
mBatLevelValue[mNumBatLevel] = lastBatValue = rec.batteryLevel;
mNumBatLevel++;
num++;
lastX = x;
lastY = y;
lastBatX = -1;
}
}
}
}
rec = rec.next;
i++;
}
if (num == 0 || lastBatX >= 0) {
mBatLevelPath.lineTo(w, y);
mBatLevelX[mNumBatLevel] = w;
mBatLevelY[mNumBatLevel] = y;
mBatLevelValue[mNumBatLevel] = lastBatValue;
mNumBatLevel++;
}
mBatLevelPath.lineTo(w, h);
mBatLevelPath.lineTo(0, h);
mBatLevelPath.close();
} }
@Override @Override
@@ -247,29 +351,23 @@ public class BatteryHistoryChart extends View {
final int width = getWidth(); final int width = getWidth();
final int height = getHeight(); final int height = getHeight();
final long timeStart = mHistStart; canvas.drawPath(mBatLevelPath, mBatteryBackgroundPaint);
final long timeChange = mHistEnd-mHistStart;
final int batLow = mBatLow;
final int batChange = mBatHigh-mBatLow;
BatteryStats.BatteryHistoryRecord rec = mStats.getHistory();
int lastX=-1, lastY=-1;
int pos = 0;
final int N = mNumHist;
while (rec != null && pos < N) {
int x = (int)(((rec.time-timeStart)*width)/timeChange);
int y = height-1 - ((rec.batteryLevel-batLow)*height)/batChange;
if (lastX >= 0) {
canvas.drawLine(lastX, lastY, x, y, mBatteryPaint);
}
lastX = x;
lastY = y;
rec = rec.next;
pos++;
}
canvas.drawText(mDurationString, (width/2) - (mDurationStringWidth/2), canvas.drawText(mDurationString, (width/2) - (mDurationStringWidth/2),
(height/2) - ((mTextDescent-mTextAscent)/2) - mTextAscent, mTextPaint); (height/2) - ((mTextDescent-mTextAscent)/2) - mTextAscent, mTextPaint);
int lastX = mBatLevelX[0];
int lastY = mBatLevelY[0];
for (int i=1; i<mNumBatLevel; i++) {
int x = mBatLevelX[i];
int y = mBatLevelY[i];
Paint paint;
byte value = mBatLevelValue[i];
if (value <= BATTERY_CRITICAL) paint = mBatteryCriticalPaint;
else if (value <= BATTERY_WARN) paint = mBatteryWarnPaint;
else paint = mBatteryGoodPaint;
canvas.drawLine(lastX, lastY, x, y, paint);
lastX = x;
lastY = y;
}
} }
} }

View File

@@ -71,7 +71,7 @@ public class PowerUsageSummary extends PreferenceActivity implements Runnable {
private PreferenceGroup mAppListGroup; private PreferenceGroup mAppListGroup;
private int mStatsType = BatteryStats.STATS_UNPLUGGED; private int mStatsType = BatteryStats.STATS_SINCE_CHARGED;
private static final int MIN_POWER_THRESHOLD = 5; private static final int MIN_POWER_THRESHOLD = 5;
private static final int MAX_ITEMS_TO_LIST = 10; private static final int MAX_ITEMS_TO_LIST = 10;
@@ -115,6 +115,9 @@ public class PowerUsageSummary extends PreferenceActivity implements Runnable {
@Override @Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
if (!(preference instanceof PowerGaugePreference)) {
return false;
}
PowerGaugePreference pgp = (PowerGaugePreference) preference; PowerGaugePreference pgp = (PowerGaugePreference) preference;
BatterySipper sipper = pgp.getInfo(); BatterySipper sipper = pgp.getInfo();
Intent intent = new Intent(this, PowerUsageDetail.class); Intent intent = new Intent(this, PowerUsageDetail.class);
@@ -213,7 +216,7 @@ public class PowerUsageSummary extends PreferenceActivity implements Runnable {
@Override @Override
public boolean onPrepareOptionsMenu(Menu menu) { public boolean onPrepareOptionsMenu(Menu menu) {
if (DEBUG) { if (DEBUG) {
menu.findItem(MENU_STATS_TYPE).setTitle(mStatsType == BatteryStats.STATS_TOTAL menu.findItem(MENU_STATS_TYPE).setTitle(mStatsType == BatteryStats.STATS_SINCE_CHARGED
? R.string.menu_stats_unplugged ? R.string.menu_stats_unplugged
: R.string.menu_stats_total); : R.string.menu_stats_total);
} }
@@ -224,10 +227,10 @@ public class PowerUsageSummary extends PreferenceActivity implements Runnable {
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case MENU_STATS_TYPE: case MENU_STATS_TYPE:
if (mStatsType == BatteryStats.STATS_TOTAL) { if (mStatsType == BatteryStats.STATS_SINCE_CHARGED) {
mStatsType = BatteryStats.STATS_UNPLUGGED; mStatsType = BatteryStats.STATS_SINCE_UNPLUGGED;
} else { } else {
mStatsType = BatteryStats.STATS_TOTAL; mStatsType = BatteryStats.STATS_SINCE_CHARGED;
} }
refreshStats(); refreshStats();
return true; return true;