BatteryHistorypublic class BatteryHistory extends android.app.Activity implements android.view.View.OnClickListener, android.widget.AdapterView.OnItemSelectedListener
Fields Summary |
---|
private static final String | TAG | private static final int | SECONDS_PER_MINUTE | private static final int | SECONDS_PER_HOUR | private static final int | SECONDS_PER_DAY | private static final int | CPU_USAGE | private static final int | NETWORK_USAGE | private static final int | GPS_USAGE | private static final int | SENSOR_USAGE | private static final int | WAKELOCK_USAGE | private static final int | MISC_USAGE | private static final int | UNPLUGGED | private static final int | CURRENT | private static final int | TOTAL | private android.os.BatteryStats | mStats | private int | mWhich | private int | mType | private GraphableButton[] | mButtons | com.android.internal.app.IBatteryStats | mBatteryInfo | private List | mCpuUsage | private List | mNetworkUsage | private List | mSensorUsage | private List | mGpsUsage | private List | mWakelockUsage | private List | mMiscUsage | private boolean | mHaveCpuUsage | private boolean | mHaveNetworkUsage | private boolean | mHaveSensorUsage | private boolean | mHaveWakelockUsage | private boolean | mHaveMiscUsage | private android.widget.LinearLayout | mGraphLayout | private android.widget.LinearLayout | mTextLayout | private android.widget.TextView | mMessageText | private android.widget.TextView | mDetailsText | private android.widget.Button | mDetailsBackButton | private android.widget.Spinner | mTypeSpinner | private android.widget.Spinner | mWhichSpinner | private boolean | mDetailsShown | private final StringBuilder | mFormatBuilder | private final Formatter | mFormatter |
Methods Summary |
---|
private void | collectStatistics()
if (mType == CPU_USAGE) {
if (!mHaveCpuUsage) {
mHaveCpuUsage = true;
processCpuUsage();
}
}
if (mType == NETWORK_USAGE) {
if (!mHaveNetworkUsage) {
mHaveNetworkUsage = true;
processNetworkUsage();
}
}
if (mType == GPS_USAGE || mType == SENSOR_USAGE) {
if (!mHaveSensorUsage) {
mHaveSensorUsage = true;
processSensorUsage();
}
}
if (mType == WAKELOCK_USAGE) {
if (!mHaveWakelockUsage) {
mHaveWakelockUsage = true;
processWakelockUsage();
}
}
if (mType == MISC_USAGE) {
if (!mHaveMiscUsage) {
mHaveMiscUsage = true;
processMiscUsage();
}
}
| private void | displayGraph()
Log.i(TAG, "displayGraph");
collectStatistics();
// Hide the UI and selectively enable it below
mMessageText.setVisibility(View.GONE);
for (int i = 0; i < mButtons.length; i++) {
mButtons[i].setVisibility(View.INVISIBLE);
}
double maxValue = -Double.MAX_VALUE;
List<? extends Graphable> records = getGraphRecords();
for (Graphable g : records) {
double[] values = g.getValues();
maxValue = Math.max(maxValue, values[values.length - 1]);
maxValue = Math.max(maxValue, g.getMaxValue());
}
int[] colors = new int[2];
colors[0] = 0xff0000ff;
colors[1] = 0xffff0000;
for (int i = 0; i < mButtons.length; i++) {
mButtons[i].setVisibility(View.INVISIBLE);
}
int numRecords = Math.min(records.size(), mButtons.length);
if (numRecords == 0) {
mMessageText.setVisibility(View.VISIBLE);
mMessageText.setText(R.string.battery_history_no_data);
} else {
for (int i = 0; i < numRecords; i++) {
Graphable r = records.get(i);
mButtons[i].setText(r.getLabel());
mButtons[i].setValues(r.getValues(), maxValue);
mButtons[i].setVisibility(View.VISIBLE);
}
}
| private final java.lang.String | formatRatio(long num, long den)
if (den == 0L) {
return "---%";
}
float perc = ((float)num) / ((float)den) * 100;
mFormatBuilder.setLength(0);
mFormatter.format("%.1f%%", perc);
return mFormatBuilder.toString();
| void | formatTime(double millis, java.lang.StringBuilder sb)
int seconds = (int) Math.floor(millis / 1000);
int days = 0, hours = 0, minutes = 0;
if (seconds > SECONDS_PER_DAY) {
days = seconds / SECONDS_PER_DAY;
seconds -= days * SECONDS_PER_DAY;
}
if (seconds > SECONDS_PER_HOUR) {
hours = seconds / SECONDS_PER_HOUR;
seconds -= hours * SECONDS_PER_HOUR;
}
if (seconds > SECONDS_PER_MINUTE) {
minutes = seconds / SECONDS_PER_MINUTE;
seconds -= minutes * SECONDS_PER_MINUTE;
}
if (days > 0) {
sb.append(getString(R.string.battery_history_days, days, hours, minutes, seconds));
} else if (hours > 0) {
sb.append(getString(R.string.battery_history_hours, hours, minutes, seconds));
} else if (minutes > 0) {
sb.append(getString(R.string.battery_history_minutes, minutes, seconds));
} else {
sb.append(getString(R.string.battery_history_seconds, seconds));
}
| private java.util.List | getGraphRecords()
switch (mType) {
case CPU_USAGE: return mCpuUsage;
case NETWORK_USAGE : return mNetworkUsage;
case SENSOR_USAGE: return mSensorUsage;
case GPS_USAGE: return mGpsUsage;
case WAKELOCK_USAGE: return mWakelockUsage;
case MISC_USAGE: return mMiscUsage;
default:
return (List<? extends Graphable>) null; // TODO
}
| private static java.lang.String | getLabel(java.lang.String packageName, android.content.pm.PackageManager pm)
try {
ApplicationInfo ai = pm.getApplicationInfo(packageName, 0);
CharSequence label = ai.loadLabel(pm);
if (label != null) {
return label.toString();
}
} catch (NameNotFoundException e) {
return packageName;
}
return "";
| private void | hideDetails()
mTextLayout.setVisibility(View.GONE);
mGraphLayout.setVisibility(View.VISIBLE);
mDetailsShown = false;
| private void | load()
try {
byte[] data = mBatteryInfo.getStatistics();
Parcel parcel = Parcel.obtain();
//Log.i(TAG, "Got data: " + data.length + " bytes");
parcel.unmarshall(data, 0, data.length);
parcel.setDataPosition(0);
mStats = com.android.internal.os.BatteryStatsImpl.CREATOR
.createFromParcel(parcel);
//Log.i(TAG, "RECEIVED BATTERY INFO:");
//mStats.dumpLocked(new LogPrinter(Log.INFO, TAG));
mHaveCpuUsage = mHaveNetworkUsage = mHaveSensorUsage
= mHaveWakelockUsage = mHaveMiscUsage = false;
} catch (RemoteException e) {
Log.e(TAG, "RemoteException:", e);
}
| public void | onClick(android.view.View v)
if (v == mDetailsBackButton) {
hideDetails();
return;
}
int id = ((Integer) v.getTag()).intValue();
showDetails(id);
| public void | onCreate(android.os.Bundle icicle)
super.onCreate(icicle);
Log.i(TAG, "onCreate");
setContentView(R.layout.battery_history);
mStats = (BatteryStats)getLastNonConfigurationInstance();
if (icicle != null) {
if (mStats == null) {
mStats = (BatteryStats)icicle.getParcelable("stats");
}
mType = icicle.getInt("type");
mWhich = icicle.getInt("which");
}
mGraphLayout = (LinearLayout) findViewById(R.id.graphLayout);
mTextLayout = (LinearLayout) findViewById(R.id.textLayout);
mDetailsText = (TextView) findViewById(R.id.detailsText);
mMessageText = (TextView) findViewById(R.id.messageText);
mTypeSpinner = (Spinner) findViewById(R.id.typeSpinner);
mTypeSpinner.setSelection(mType);
mTypeSpinner.setOnItemSelectedListener(this);
mWhichSpinner = (Spinner) findViewById(R.id.whichSpinner);
mWhichSpinner.setOnItemSelectedListener(this);
mWhichSpinner.setEnabled(true);
mButtons = new GraphableButton[8];
mButtons[0] = (GraphableButton) findViewById(R.id.button0);
mButtons[1] = (GraphableButton) findViewById(R.id.button1);
mButtons[2] = (GraphableButton) findViewById(R.id.button2);
mButtons[3] = (GraphableButton) findViewById(R.id.button3);
mButtons[4] = (GraphableButton) findViewById(R.id.button4);
mButtons[5] = (GraphableButton) findViewById(R.id.button5);
mButtons[6] = (GraphableButton) findViewById(R.id.button6);
mButtons[7] = (GraphableButton) findViewById(R.id.button7);
for (int i = 0; i < mButtons.length; i++) {
mButtons[i].setTag(i);
mButtons[i].setOnClickListener(this);
}
mBatteryInfo = IBatteryStats.Stub.asInterface(
ServiceManager.getService("batteryinfo"));
if (mStats == null) {
load();
}
displayGraph();
| public void | onItemSelected(android.widget.AdapterView parent, android.view.View view, int position, long id)
int oldWhich = mWhich;
if (parent.equals(mTypeSpinner)) {
mType = position;
} else if (parent.equals(mWhichSpinner)) {
switch (position) {
case UNPLUGGED:
mWhich = BatteryStats.STATS_UNPLUGGED;
break;
case CURRENT:
mWhich = BatteryStats.STATS_CURRENT;
break;
case TOTAL:
mWhich = BatteryStats.STATS_TOTAL;
break;
}
}
if (oldWhich != mWhich) {
mHaveCpuUsage = mHaveNetworkUsage = mHaveSensorUsage
= mHaveWakelockUsage = mHaveMiscUsage = false;
}
displayGraph();
| public boolean | onKeyDown(int keyCode, android.view.KeyEvent event)
if (keyCode == KeyEvent.KEYCODE_BACK && mDetailsShown) {
hideDetails();
return true;
}
return super.onKeyDown(keyCode, event);
| public void | onNothingSelected(android.widget.AdapterView parent)
// Do nothing
| public java.lang.Object | onRetainNonConfigurationInstance()
BatteryStats stats = mStats;
mStats = null;
return stats;
| protected void | onSaveInstanceState(android.os.Bundle outState)
super.onSaveInstanceState(outState);
if (mStats != null) {
outState.putParcelable("stats", mStats);
}
outState.putInt("type", mType);
outState.putInt("which", mWhich);
| private void | processCpuUsage()
mCpuUsage.clear();
long uSecTime = SystemClock.uptimeMillis() * 1000;
final long uSecNow = mStats.computeBatteryUptime(uSecTime, mWhich) / 1000;
SparseArray<? extends Uid> uidStats = mStats.getUidStats();
final int NU = uidStats.size();
for (int iu = 0; iu < NU; iu++) {
Uid u = uidStats.valueAt(iu);
Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
if (processStats.size() > 0) {
for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
: processStats.entrySet()) {
Uid.Proc ps = ent.getValue();
long userTime = ps.getUserTime(mWhich);
long systemTime = ps.getSystemTime(mWhich);
long starts = ps.getStarts(mWhich);
if (userTime != 0 || systemTime != 0) {
mCpuUsage.add(new CpuUsage(u.getUid(), ent.getKey(),
userTime, systemTime, starts, uSecNow));
}
}
}
}
Collections.sort(mCpuUsage);
| private void | processMiscUsage()
mMiscUsage.clear();
long rawRealtime = SystemClock.elapsedRealtime() * 1000;
final long batteryRealtime = mStats.getBatteryRealtime(rawRealtime);
final long whichRealtime = mStats.computeBatteryRealtime(rawRealtime, mWhich) / 1000;
long time = mStats.computeBatteryUptime(SystemClock.uptimeMillis() * 1000, mWhich) / 1000;
if (time > 0) {
mMiscUsage.add(new MiscUsage(getString(
R.string.battery_history_awake_label)
+ " (" + formatRatio(time, whichRealtime) + ")",
R.string.battery_history_awake,
time, whichRealtime));
}
time = mStats.getScreenOnTime(batteryRealtime, mWhich) / 1000;
if (time > 0) {
mMiscUsage.add(new MiscUsage(getString(
R.string.battery_history_screen_on_label)
+ " (" + formatRatio(time, whichRealtime) + ")",
R.string.battery_history_screen_on,
time, whichRealtime));
}
time = mStats.getPhoneOnTime(batteryRealtime, mWhich) / 1000;
if (time > 0) {
mMiscUsage.add(new MiscUsage(getString(
R.string.battery_history_phone_on_label)
+ " (" + formatRatio(time, whichRealtime) + ")",
R.string.battery_history_phone_on,
time, whichRealtime));
}
time = mStats.getWifiOnTime(batteryRealtime, mWhich) / 1000;
if (time > 0) {
mMiscUsage.add(new MiscUsage("Wifi On ("
+ formatRatio(time, whichRealtime) + ")",
"Time spent with Wifi on:",
time, whichRealtime));
}
time = mStats.getWifiRunningTime(batteryRealtime, mWhich) / 1000;
if (time > 0) {
mMiscUsage.add(new MiscUsage("Wifi Running ("
+ formatRatio(time, whichRealtime) + ")",
"Time spent with Wifi running:",
time, whichRealtime));
}
time = mStats.getBluetoothOnTime(batteryRealtime, mWhich) / 1000;
if (time > 0) {
mMiscUsage.add(new MiscUsage("Bluetooth On ("
+ formatRatio(time, whichRealtime) + ")",
"Time spent with Bluetooth on:",
time, whichRealtime));
}
Collections.sort(mMiscUsage);
| private void | processNetworkUsage()
mNetworkUsage.clear();
SparseArray<? extends Uid> uidStats = mStats.getUidStats();
final int NU = uidStats.size();
for (int iu = 0; iu < NU; iu++) {
Uid u = uidStats.valueAt(iu);
long received = u.getTcpBytesReceived(mWhich);
long sent = u.getTcpBytesSent(mWhich);
if (received + sent > 0) {
mNetworkUsage.add(new NetworkUsage(u.getUid(), received, sent));
}
}
Collections.sort(mNetworkUsage);
| private void | processSensorUsage()
mGpsUsage.clear();
mSensorUsage.clear();
long uSecTime = SystemClock.elapsedRealtime() * 1000;
final long uSecNow = mStats.computeBatteryRealtime(uSecTime, mWhich) / 1000;
SparseArray<? extends Uid> uidStats = mStats.getUidStats();
final int NU = uidStats.size();
for (int iu = 0; iu < NU; iu++) {
Uid u = uidStats.valueAt(iu);
int uid = u.getUid();
Map<Integer, ? extends BatteryStats.Uid.Sensor> sensorStats = u.getSensorStats();
long timeGps = 0;
int countGps = 0;
long timeOther = 0;
int countOther = 0;
if (sensorStats.size() > 0) {
for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> ent
: sensorStats.entrySet()) {
Uid.Sensor se = ent.getValue();
int handle = se.getHandle();
Timer timer = se.getSensorTime();
if (timer != null) {
// Convert from microseconds to milliseconds with rounding
long totalTime = (timer.getTotalTime(uSecNow, mWhich) + 500) / 1000;
int count = timer.getCount(mWhich);
if (handle == BatteryStats.Uid.Sensor.GPS) {
timeGps += totalTime;
countGps += count;
} else {
timeOther += totalTime;
countOther += count;
}
}
}
}
if (timeGps > 0) {
mGpsUsage.add(new SensorUsage(uid, timeGps, countGps, uSecNow));
}
if (timeOther > 0) {
mSensorUsage.add(new SensorUsage(uid, timeOther, countOther, uSecNow));
}
}
Collections.sort(mGpsUsage);
Collections.sort(mSensorUsage);
| private void | processWakelockUsage()
mWakelockUsage.clear();
long uSecTime = SystemClock.elapsedRealtime() * 1000;
final long uSecNow = mStats.computeBatteryRealtime(uSecTime, mWhich) / 1000;
SparseArray<? extends Uid> uidStats = mStats.getUidStats();
final int NU = uidStats.size();
for (int iu = 0; iu < NU; iu++) {
Uid u = uidStats.valueAt(iu);
int uid = u.getUid();
Map<String, ? extends BatteryStats.Uid.Wakelock> wakelockStats = u.getWakelockStats();
long time = 0;
int count = 0;
if (wakelockStats.size() > 0) {
for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> ent
: wakelockStats.entrySet()) {
Uid.Wakelock wl = ent.getValue();
Timer timer = wl.getWakeTime(BatteryStats.WAKE_TYPE_PARTIAL);
if (timer != null) {
// Convert from microseconds to milliseconds with rounding
time += (timer.getTotalTime(uSecNow, mWhich) + 500) / 1000;
count += timer.getCount(mWhich);
}
}
}
if (time > 0) {
mWakelockUsage.add(new WakelockUsage(uid, time, count, uSecNow));
}
}
Collections.sort(mWakelockUsage);
| private void | showDetails(int id)
mGraphLayout.setVisibility(View.GONE);
mTextLayout.setVisibility(View.VISIBLE);
StringBuilder info = new StringBuilder();
List<? extends Graphable> records = getGraphRecords();
if (id < records.size()) {
Graphable record = records.get(id);
record.getInfo(info);
} else {
info.append(getString(R.string.battery_history_details_for, id));
}
mDetailsText.setText(info.toString());
mDetailsShown = true;
|
|