diff options
5 files changed, 107 insertions, 20 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 6e6e86f78950..72bf825ea2c3 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -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. */ diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index 1e88c5647666..ba8014f2a3fa 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -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(""); } diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index c2d003e96293..6e5c47fa1044 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -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 { diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index 9835098baa78..d7a1ac25223a 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -8316,6 +8316,11 @@ public class WindowManagerService extends IWindowManager.Stub return; } + if (mDisplay == null) { + // Not yet initialized, nothing to do. + return; + } + boolean recoveringMemory = false; if (mForceRemoves != null) { recoveringMemory = true; diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index cf767ca878cf..3172077132f4 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -1383,7 +1383,7 @@ public final class ActivityManagerService extends ActivityManagerNative mBatteryStatsService = new BatteryStatsService(new File( systemDir, "batterystats.bin").toString()); mBatteryStatsService.getActiveStatistics().readLocked(); - mBatteryStatsService.getActiveStatistics().writeLocked(); + mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); mOnBattery = mBatteryStatsService.getActiveStatistics().getIsOnBattery(); mBatteryStatsService.getActiveStatistics().setCallback(this); @@ -1536,7 +1536,7 @@ public final class ActivityManagerService extends ActivityManagerNative if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { mLastWriteTime = now; - mBatteryStatsService.getActiveStatistics().writeLocked(); + mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); } } } |