diff options
| -rw-r--r-- | core/java/android/app/ActivityThread.java | 8 | ||||
| -rw-r--r-- | services/java/com/android/server/am/ActivityManagerService.java | 8 | ||||
| -rwxr-xr-x | services/java/com/android/server/am/ActivityStack.java | 49 |
3 files changed, 53 insertions, 12 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index b55ee26a500b..314f5c2e3f80 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -136,7 +136,7 @@ public final class ActivityThread { /** @hide */ public static final boolean DEBUG_BROADCAST = false; private static final boolean DEBUG_RESULTS = false; - private static final boolean DEBUG_BACKUP = true; + private static final boolean DEBUG_BACKUP = false; private static final boolean DEBUG_CONFIGURATION = false; private static final boolean DEBUG_SERVICE = false; private static final boolean DEBUG_MEMORY_TRIM = false; @@ -1172,10 +1172,10 @@ public final class ActivityThread { case DUMP_PROVIDER: return "DUMP_PROVIDER"; } } - return "(unknown)"; + return Integer.toString(code); } public void handleMessage(Message msg) { - if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + msg.what); + if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what)); switch (msg.what) { case LAUNCH_ACTIVITY: { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); @@ -1378,7 +1378,7 @@ public final class ActivityThread { Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; } - if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + msg.what); + if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what)); } private void maybeSnapshot() { diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 4b40107dfa49..1f7aeb0b4deb 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -14508,9 +14508,11 @@ public final class ActivityManagerService extends ActivityManagerNative // activities causes more harm than good. if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE && app != mHomeProcess && app != mPreviousProcess) { + // Need to do this on its own message because the stack may not + // be in a consistent state at this point. // For these apps we will also finish their activities // to help them free memory. - mMainStack.destroyActivitiesLocked(app, false, "trim"); + mMainStack.scheduleDestroyActivities(app, false, "trim"); } } } @@ -14582,7 +14584,9 @@ public final class ActivityManagerService extends ActivityManagerNative } if (mAlwaysFinishActivities) { - mMainStack.destroyActivitiesLocked(null, false, "always-finish"); + // Need to do this on its own message because the stack may not + // be in a consistent state at this point. + mMainStack.scheduleDestroyActivities(null, false, "always-finish"); } } diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index 25fae830820c..1e14f5b55974 100755 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -45,7 +45,6 @@ import android.content.pm.ResolveInfo; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Bitmap; -import android.net.Uri; import android.os.Binder; import android.os.Bundle; import android.os.Handler; @@ -289,7 +288,19 @@ final class ActivityStack { static final int RESUME_TOP_ACTIVITY_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 6; static final int LAUNCH_TICK_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 7; static final int STOP_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 8; - + static final int DESTROY_ACTIVITIES_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 9; + + static class ScheduleDestroyArgs { + final ProcessRecord mOwner; + final boolean mOomAdj; + final String mReason; + ScheduleDestroyArgs(ProcessRecord owner, boolean oomAdj, String reason) { + mOwner = owner; + mOomAdj = oomAdj; + mReason = reason; + } + } + final Handler mHandler = new Handler() { //public Handler() { // if (localLOGV) Slog.v(TAG, "Handler started!"); @@ -384,6 +395,12 @@ final class ActivityStack { } } } break; + case DESTROY_ACTIVITIES_MSG: { + ScheduleDestroyArgs args = (ScheduleDestroyArgs)msg.obj; + synchronized (mService) { + destroyActivitiesLocked(args.mOwner, args.mOomAdj, args.mReason); + } + } } } }; @@ -3821,19 +3838,39 @@ final class ActivityStack { r.connections = null; } } - + + final void scheduleDestroyActivities(ProcessRecord owner, boolean oomAdj, String reason) { + Message msg = mHandler.obtainMessage(DESTROY_ACTIVITIES_MSG); + msg.obj = new ScheduleDestroyArgs(owner, oomAdj, reason); + mHandler.sendMessage(msg); + } + final void destroyActivitiesLocked(ProcessRecord owner, boolean oomAdj, String reason) { + boolean lastIsOpaque = false; for (int i=mHistory.size()-1; i>=0; i--) { ActivityRecord r = mHistory.get(i); + if (r.finishing) { + continue; + } + if (r.fullscreen) { + lastIsOpaque = true; + } if (owner != null && r.app != owner) { continue; } + if (!lastIsOpaque) { + continue; + } // We can destroy this one if we have its icicle saved and // it is not in the process of pausing/stopping/finishing. - if (r.app != null && r.haveState && !r.visible && r.stopped && !r.finishing + if (r.app != null && r != mResumedActivity && r != mPausingActivity + && r.haveState && !r.visible && r.stopped && r.state != ActivityState.DESTROYING && r.state != ActivityState.DESTROYED) { - destroyActivityLocked(r, true, oomAdj, "trim"); + if (DEBUG_SWITCH) Slog.v(TAG, "Destroying " + r + " in state " + r.state + + " resumed=" + mResumedActivity + + " pausing=" + mPausingActivity); + destroyActivityLocked(r, true, oomAdj, reason); } } } @@ -3847,7 +3884,7 @@ final class ActivityStack { final boolean destroyActivityLocked(ActivityRecord r, boolean removeFromApp, boolean oomAdj, String reason) { if (DEBUG_SWITCH) Slog.v( - TAG, "Removing activity: token=" + r + TAG, "Removing activity from " + reason + ": token=" + r + ", app=" + (r.app != null ? r.app.processName : "(null)")); EventLog.writeEvent(EventLogTags.AM_DESTROY_ACTIVITY, System.identityHashCode(r), |