summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/ActivityThread.java8
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java8
-rwxr-xr-xservices/java/com/android/server/am/ActivityStack.java49
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),