Some battery improvements:
- New API for iterating over history that will allow a better implementation in the future. - Now do writes asynchronously. Also improve the documentation for Activity.onRetainNonInstanceState(). Change-Id: Idf67f2796a8868eb62f288bcbb2bad29876c8554
This commit is contained in:
@@ -1427,7 +1427,9 @@ public class Activity extends ContextThemeWrapper
|
||||
* <li> The function will be called between {@link #onStop} and
|
||||
* {@link #onDestroy}.
|
||||
* <li> A new instance of the activity will <em>always</em> be immediately
|
||||
* created after this one's {@link #onDestroy()} is called.
|
||||
* created after this one's {@link #onDestroy()} is called. In particular,
|
||||
* <em>no</em> messages will be dispatched during this time (when the returned
|
||||
* object does not have an activity to be associated with).
|
||||
* <li> The object you return here will <em>always</em> be available from
|
||||
* the {@link #getLastNonConfigurationInstance()} method of the following
|
||||
* activity instance as described there.
|
||||
@@ -1440,6 +1442,15 @@ public class Activity extends ContextThemeWrapper
|
||||
* may change based on the configuration, including any data loaded from
|
||||
* resources such as strings, layouts, or drawables.
|
||||
*
|
||||
* <p>The guarantee of no message handling during the switch to the next
|
||||
* activity simplifies use with active objects. For example if your retained
|
||||
* state is an {@link android.os.AsyncTask} you are guaranteed that its
|
||||
* call back functions (like {@link android.os.AsyncTask#onPostExecute}) will
|
||||
* not be called from the call here until you execute the next instance's
|
||||
* {@link #onCreate(Bundle)}. (Note however that there is of course no such
|
||||
* guarantee for {@link android.os.AsyncTask#doInBackground} since that is
|
||||
* running in a separate thread.)
|
||||
*
|
||||
* @return Return any Object holding the desired state to propagate to the
|
||||
* next activity instance.
|
||||
*/
|
||||
|
||||
@@ -397,7 +397,7 @@ public abstract class BatteryStats implements Parcelable {
|
||||
}
|
||||
}
|
||||
|
||||
public final class HistoryItem implements Parcelable {
|
||||
public final static class HistoryItem implements Parcelable {
|
||||
public HistoryItem next;
|
||||
|
||||
public long time;
|
||||
@@ -482,6 +482,18 @@ public abstract class BatteryStats implements Parcelable {
|
||||
dest.writeInt(states);
|
||||
}
|
||||
|
||||
public void setTo(HistoryItem o) {
|
||||
time = o.time;
|
||||
cmd = o.cmd;
|
||||
batteryLevel = o.batteryLevel;
|
||||
batteryStatus = o.batteryStatus;
|
||||
batteryHealth = o.batteryHealth;
|
||||
batteryPlugType = o.batteryPlugType;
|
||||
batteryTemperature = o.batteryTemperature;
|
||||
batteryVoltage = o.batteryVoltage;
|
||||
states = o.states;
|
||||
}
|
||||
|
||||
public void setTo(long time, byte cmd, HistoryItem o) {
|
||||
this.time = time;
|
||||
this.cmd = cmd;
|
||||
@@ -526,6 +538,10 @@ public abstract class BatteryStats implements Parcelable {
|
||||
}
|
||||
}
|
||||
|
||||
public abstract boolean startIteratingHistoryLocked();
|
||||
|
||||
public abstract boolean getNextHistoryLocked(HistoryItem out);
|
||||
|
||||
/**
|
||||
* Return the current history of battery state changes.
|
||||
*/
|
||||
@@ -1688,8 +1704,8 @@ public abstract class BatteryStats implements Parcelable {
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public void dumpLocked(PrintWriter pw) {
|
||||
HistoryItem rec = getHistory();
|
||||
if (rec != null) {
|
||||
final HistoryItem rec = new HistoryItem();
|
||||
if (startIteratingHistoryLocked()) {
|
||||
pw.println("Battery History:");
|
||||
long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
|
||||
int oldState = 0;
|
||||
@@ -1698,7 +1714,7 @@ public abstract class BatteryStats implements Parcelable {
|
||||
int oldPlug = -1;
|
||||
int oldTemp = -1;
|
||||
int oldVolt = -1;
|
||||
while (rec != null) {
|
||||
while (getNextHistoryLocked(rec)) {
|
||||
pw.print(" ");
|
||||
TimeUtils.formatDuration(rec.time-now, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN);
|
||||
pw.print(" ");
|
||||
@@ -1803,7 +1819,6 @@ public abstract class BatteryStats implements Parcelable {
|
||||
pw.println();
|
||||
}
|
||||
oldState = rec.states;
|
||||
rec = rec.next;
|
||||
}
|
||||
pw.println("");
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
/**
|
||||
* All information we are collecting about things that can happen that impact
|
||||
@@ -3834,6 +3835,22 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
}
|
||||
}
|
||||
|
||||
private HistoryItem mHistoryIterator;
|
||||
|
||||
public boolean startIteratingHistoryLocked() {
|
||||
return (mHistoryIterator = mHistory) != null;
|
||||
}
|
||||
|
||||
public boolean getNextHistoryLocked(HistoryItem out) {
|
||||
HistoryItem cur = mHistoryIterator;
|
||||
if (cur == null) {
|
||||
return false;
|
||||
}
|
||||
out.setTo(cur);
|
||||
mHistoryIterator = cur.next;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HistoryItem getHistory() {
|
||||
return mHistory;
|
||||
@@ -3960,7 +3977,7 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
}
|
||||
if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) {
|
||||
if (mFile != null) {
|
||||
writeLocked();
|
||||
writeAsyncLocked();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4356,11 +4373,22 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
}
|
||||
|
||||
public void shutdownLocked() {
|
||||
writeLocked();
|
||||
writeSyncLocked();
|
||||
mShuttingDown = true;
|
||||
}
|
||||
|
||||
public void writeLocked() {
|
||||
Parcel mPendingWrite = null;
|
||||
final ReentrantLock mWriteLock = new ReentrantLock();
|
||||
|
||||
public void writeAsyncLocked() {
|
||||
writeLocked(false);
|
||||
}
|
||||
|
||||
public void writeSyncLocked() {
|
||||
writeLocked(true);
|
||||
}
|
||||
|
||||
void writeLocked(boolean sync) {
|
||||
if (mFile == null) {
|
||||
Slog.w("BatteryStats", "writeLocked: no file associated with this instance");
|
||||
return;
|
||||
@@ -4370,23 +4398,51 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
return;
|
||||
}
|
||||
|
||||
Parcel out = Parcel.obtain();
|
||||
writeSummaryToParcel(out);
|
||||
mLastWriteTime = SystemClock.elapsedRealtime();
|
||||
|
||||
if (mPendingWrite != null) {
|
||||
mPendingWrite.recycle();
|
||||
}
|
||||
mPendingWrite = out;
|
||||
|
||||
if (sync) {
|
||||
commitPendingDataToDisk();
|
||||
} else {
|
||||
Thread thr = new Thread("BatteryStats-Write") {
|
||||
@Override
|
||||
public void run() {
|
||||
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
|
||||
commitPendingDataToDisk();
|
||||
}
|
||||
};
|
||||
thr.start();
|
||||
}
|
||||
}
|
||||
|
||||
public void commitPendingDataToDisk() {
|
||||
Parcel next;
|
||||
synchronized (this) {
|
||||
next = mPendingWrite;
|
||||
mPendingWrite = null;
|
||||
|
||||
mWriteLock.lock();
|
||||
}
|
||||
|
||||
try {
|
||||
FileOutputStream stream = new FileOutputStream(mFile.chooseForWrite());
|
||||
Parcel out = Parcel.obtain();
|
||||
writeSummaryToParcel(out);
|
||||
stream.write(out.marshall());
|
||||
out.recycle();
|
||||
|
||||
stream.write(next.marshall());
|
||||
stream.flush();
|
||||
stream.close();
|
||||
mFile.commit();
|
||||
|
||||
mLastWriteTime = SystemClock.elapsedRealtime();
|
||||
return;
|
||||
} catch (IOException e) {
|
||||
Slog.w("BatteryStats", "Error writing battery statistics", e);
|
||||
mFile.rollback();
|
||||
} finally {
|
||||
next.recycle();
|
||||
mWriteLock.unlock();
|
||||
}
|
||||
mFile.rollback();
|
||||
}
|
||||
|
||||
static byte[] readFully(FileInputStream stream) throws java.io.IOException {
|
||||
|
||||
Reference in New Issue
Block a user