summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2012-10-01 17:42:02 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2012-10-01 17:46:27 -0700
commit6f354ed9994b4ea7612cc4499413de108dcac7d4 (patch)
tree45d8641308341f9ab8f801e82deb9edc9e5d7fb9
parent046cff13fc897e9e958ef387884eb97fd901840b (diff)
parentcc5a055613efb463275633d83a04674b0be6d770 (diff)
downloadframeworks_base-6f354ed9994b4ea7612cc4499413de108dcac7d4.zip
frameworks_base-6f354ed9994b4ea7612cc4499413de108dcac7d4.tar.gz
frameworks_base-6f354ed9994b4ea7612cc4499413de108dcac7d4.tar.bz2
Merge "Fix issue #7226101: Secure image capture takes 5 seconds to start" into jb-mr1-dev
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java71
-rwxr-xr-xservices/java/com/android/server/am/ActivityStack.java143
2 files changed, 113 insertions, 101 deletions
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 35f1b59..e90eef9 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -181,6 +181,7 @@ public final class ActivityManagerService extends ActivityManagerNative
static final boolean DEBUG_VISBILITY = localLOGV || false;
static final boolean DEBUG_PROCESSES = localLOGV || false;
static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
+ static final boolean DEBUG_CLEANUP = localLOGV || false;
static final boolean DEBUG_PROVIDER = localLOGV || false;
static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
static final boolean DEBUG_USER_LEAVING = localLOGV || false;
@@ -1968,7 +1969,7 @@ public final class ActivityManagerService extends ActivityManagerNative
} else {
// An application record is attached to a previous process,
// clean it up now.
- if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
+ if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
handleAppDiedLocked(app, true, true);
}
}
@@ -2925,7 +2926,8 @@ public final class ActivityManagerService extends ActivityManagerNative
// Just in case...
if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
- if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
+ if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG,
+ "App died while pausing: " + mMainStack.mPausingActivity);
mMainStack.mPausingActivity = null;
}
if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
@@ -2933,61 +2935,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
// Remove this application's activities from active lists.
- mMainStack.removeHistoryRecordsForAppLocked(app);
-
- boolean atTop = true;
- boolean hasVisibleActivities = false;
-
- // Clean out the history list.
- int i = mMainStack.mHistory.size();
- if (localLOGV) Slog.v(
- TAG, "Removing app " + app + " from history with " + i + " entries");
- while (i > 0) {
- i--;
- ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
- if (localLOGV) Slog.v(
- TAG, "Record #" + i + " " + r + ": app=" + r.app);
- if (r.app == app) {
- if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
- if (ActivityStack.DEBUG_ADD_REMOVE) {
- RuntimeException here = new RuntimeException("here");
- here.fillInStackTrace();
- Slog.i(TAG, "Removing activity " + r + " from stack at " + i
- + ": haveState=" + r.haveState
- + " stateNotNeeded=" + r.stateNotNeeded
- + " finishing=" + r.finishing
- + " state=" + r.state, here);
- }
- if (!r.finishing) {
- Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
- EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
- r.userId, System.identityHashCode(r),
- r.task.taskId, r.shortComponentName,
- "proc died without state saved");
- }
- mMainStack.removeActivityFromHistoryLocked(r);
-
- } else {
- // We have the current state for this activity, so
- // it can be restarted later when needed.
- if (localLOGV) Slog.v(
- TAG, "Keeping entry, setting app to null");
- if (r.visible) {
- hasVisibleActivities = true;
- }
- r.app = null;
- r.nowVisible = false;
- if (!r.haveState) {
- if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
- "App died, clearing saved state of " + r);
- r.icicle = null;
- }
- }
-
- r.stack.cleanUpActivityLocked(r, true, true);
- }
- atTop = false;
- }
+ boolean hasVisibleActivities = mMainStack.removeHistoryRecordsForAppLocked(app);
app.activities.clear();
@@ -3053,7 +3001,7 @@ public final class ActivityManagerService extends ActivityManagerNative
+ ") has died.");
}
EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
- if (localLOGV) Slog.v(
+ if (DEBUG_CLEANUP) Slog.v(
TAG, "Dying app: " + app + ", pid: " + pid
+ ", thread: " + thread.asBinder());
boolean doLowMem = app.instrumentationClass == null;
@@ -10757,7 +10705,8 @@ public final class ActivityManagerService extends ActivityManagerNative
// If the app is undergoing backup, tell the backup manager about it
if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
- if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
+ if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
+ + mBackupTarget.appInfo + " died during backup");
try {
IBackupManager bm = IBackupManager.Stub.asInterface(
ServiceManager.getService(Context.BACKUP_SERVICE));
@@ -10783,7 +10732,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
if (!app.persistent || app.isolated) {
- if (DEBUG_PROCESSES) Slog.v(TAG,
+ if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
"Removing non-persistent process during cleanup: " + app);
mProcessNames.remove(app.processName, app.uid);
mIsolatedProcesses.remove(app.uid);
@@ -10801,7 +10750,7 @@ public final class ActivityManagerService extends ActivityManagerNative
restart = true;
}
}
- if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
+ if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
"Clean-up removing on hold: " + app);
mProcessesOnHold.remove(app);
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 2d445274..90a7abc 100755
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -81,6 +81,7 @@ final class ActivityStack {
static final boolean DEBUG_RESULTS = ActivityManagerService.DEBUG_RESULTS;
static final boolean DEBUG_CONFIGURATION = ActivityManagerService.DEBUG_CONFIGURATION;
static final boolean DEBUG_TASKS = ActivityManagerService.DEBUG_TASKS;
+ static final boolean DEBUG_CLEANUP = ActivityManagerService.DEBUG_CLEANUP;
static final boolean DEBUG_STATES = false;
static final boolean DEBUG_ADD_REMOVE = false;
@@ -1142,9 +1143,13 @@ final class ActivityStack {
resumeTopActivityLocked(prev);
} else {
checkReadyForSleepLocked();
- if (topRunningActivityLocked(null) == null) {
- // If there are no more activities available to run, then
- // do resume anyway to start something.
+ ActivityRecord top = topRunningActivityLocked(null);
+ if (top == null || (prev != null && top != prev)) {
+ // If there are no more activities available to run,
+ // do resume anyway to start something. Also if the top
+ // activity on the stack is not the just paused activity,
+ // we need to go ahead and resume it to ensure we complete
+ // an in-flight app switch.
resumeTopActivityLocked(null);
}
}
@@ -1461,7 +1466,8 @@ final class ActivityStack {
// If we are currently pausing an activity, then don't do anything
// until that is done.
if (mPausingActivity != null) {
- if (DEBUG_SWITCH) Slog.v(TAG, "Skip resume: pausing=" + mPausingActivity);
+ if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(TAG,
+ "Skip resume: pausing=" + mPausingActivity);
return false;
}
@@ -3862,6 +3868,7 @@ final class ActivityStack {
if (setState) {
if (DEBUG_STATES) Slog.v(TAG, "Moving to DESTROYED: " + r + " (cleaning up)");
r.state = ActivityState.DESTROYED;
+ r.app = null;
}
// Make sure this record is no longer in the pending finishes list.
@@ -3905,26 +3912,26 @@ final class ActivityStack {
}
final void removeActivityFromHistoryLocked(ActivityRecord r) {
- if (r.state != ActivityState.DESTROYED) {
- finishActivityResultsLocked(r, Activity.RESULT_CANCELED, null);
- r.makeFinishing();
- if (DEBUG_ADD_REMOVE) {
- RuntimeException here = new RuntimeException("here");
- here.fillInStackTrace();
- Slog.i(TAG, "Removing activity " + r + " from stack");
- }
- mHistory.remove(r);
- r.takeFromHistory();
- if (DEBUG_STATES) Slog.v(TAG, "Moving to DESTROYED: " + r
- + " (removed from history)");
- r.state = ActivityState.DESTROYED;
- mService.mWindowManager.removeAppToken(r.appToken);
- if (VALIDATE_TOKENS) {
- validateAppTokensLocked();
- }
- cleanUpActivityServicesLocked(r);
- r.removeUriPermissionsLocked();
+ finishActivityResultsLocked(r, Activity.RESULT_CANCELED, null);
+ r.makeFinishing();
+ if (DEBUG_ADD_REMOVE) {
+ RuntimeException here = new RuntimeException("here");
+ here.fillInStackTrace();
+ Slog.i(TAG, "Removing activity " + r + " from stack");
+ }
+ mHistory.remove(r);
+ r.takeFromHistory();
+ removeTimeoutsForActivityLocked(r);
+ if (DEBUG_STATES) Slog.v(TAG, "Moving to DESTROYED: " + r
+ + " (removed from history)");
+ r.state = ActivityState.DESTROYED;
+ r.app = null;
+ mService.mWindowManager.removeAppToken(r.appToken);
+ if (VALIDATE_TOKENS) {
+ validateAppTokensLocked();
}
+ cleanUpActivityServicesLocked(r);
+ r.removeUriPermissionsLocked();
}
/**
@@ -3992,7 +3999,7 @@ final class ActivityStack {
*/
final boolean destroyActivityLocked(ActivityRecord r,
boolean removeFromApp, boolean oomAdj, String reason) {
- if (DEBUG_SWITCH) Slog.v(
+ if (DEBUG_SWITCH || DEBUG_CLEANUP) Slog.v(
TAG, "Removing activity from " + reason + ": token=" + r
+ ", app=" + (r.app != null ? r.app.processName : "(null)"));
EventLog.writeEvent(EventLogTags.AM_DESTROY_ACTIVITY,
@@ -4000,11 +4007,11 @@ final class ActivityStack {
r.task.taskId, r.shortComponentName, reason);
boolean removedFromHistory = false;
-
+
cleanUpActivityLocked(r, false, false);
final boolean hadApp = r.app != null;
-
+
if (hadApp) {
if (removeFromApp) {
int idx = r.app.activities.indexOf(r);
@@ -4040,7 +4047,6 @@ final class ActivityStack {
}
}
- r.app = null;
r.nowVisible = false;
// If the activity is finishing, we need to wait on removing it
@@ -4061,6 +4067,7 @@ final class ActivityStack {
if (DEBUG_STATES) Slog.v(TAG, "Moving to DESTROYED: " + r
+ " (destroy skipped)");
r.state = ActivityState.DESTROYED;
+ r.app = null;
}
} else {
// remove this record from the history.
@@ -4071,6 +4078,7 @@ final class ActivityStack {
if (DEBUG_STATES) Slog.v(TAG, "Moving to DESTROYED: " + r
+ " (no app)");
r.state = ActivityState.DESTROYED;
+ r.app = null;
}
}
@@ -4106,30 +4114,85 @@ final class ActivityStack {
}
}
- private void removeHistoryRecordsForAppLocked(ArrayList list, ProcessRecord app) {
+ private void removeHistoryRecordsForAppLocked(ArrayList list, ProcessRecord app,
+ String listName) {
int i = list.size();
- if (localLOGV) Slog.v(
- TAG, "Removing app " + app + " from list " + list
+ if (DEBUG_CLEANUP) Slog.v(
+ TAG, "Removing app " + app + " from list " + listName
+ " with " + i + " entries");
while (i > 0) {
i--;
ActivityRecord r = (ActivityRecord)list.get(i);
- if (localLOGV) Slog.v(
- TAG, "Record #" + i + " " + r + ": app=" + r.app);
+ if (DEBUG_CLEANUP) Slog.v(TAG, "Record #" + i + " " + r);
if (r.app == app) {
- if (localLOGV) Slog.v(TAG, "Removing this entry!");
+ if (DEBUG_CLEANUP) Slog.v(TAG, "---> REMOVING this entry!");
list.remove(i);
removeTimeoutsForActivityLocked(r);
}
}
}
- void removeHistoryRecordsForAppLocked(ProcessRecord app) {
- removeHistoryRecordsForAppLocked(mLRUActivities, app);
- removeHistoryRecordsForAppLocked(mStoppingActivities, app);
- removeHistoryRecordsForAppLocked(mGoingToSleepActivities, app);
- removeHistoryRecordsForAppLocked(mWaitingVisibleActivities, app);
- removeHistoryRecordsForAppLocked(mFinishingActivities, app);
+ boolean removeHistoryRecordsForAppLocked(ProcessRecord app) {
+ removeHistoryRecordsForAppLocked(mLRUActivities, app, "mLRUActivities");
+ removeHistoryRecordsForAppLocked(mStoppingActivities, app, "mStoppingActivities");
+ removeHistoryRecordsForAppLocked(mGoingToSleepActivities, app, "mGoingToSleepActivities");
+ removeHistoryRecordsForAppLocked(mWaitingVisibleActivities, app,
+ "mWaitingVisibleActivities");
+ removeHistoryRecordsForAppLocked(mFinishingActivities, app, "mFinishingActivities");
+
+ boolean hasVisibleActivities = false;
+
+ // Clean out the history list.
+ int i = mHistory.size();
+ if (DEBUG_CLEANUP) Slog.v(
+ TAG, "Removing app " + app + " from history with " + i + " entries");
+ while (i > 0) {
+ i--;
+ ActivityRecord r = (ActivityRecord)mHistory.get(i);
+ if (DEBUG_CLEANUP) Slog.v(
+ TAG, "Record #" + i + " " + r + ": app=" + r.app);
+ if (r.app == app) {
+ if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
+ if (ActivityStack.DEBUG_ADD_REMOVE || DEBUG_CLEANUP) {
+ RuntimeException here = new RuntimeException("here");
+ here.fillInStackTrace();
+ Slog.i(TAG, "Removing activity " + r + " from stack at " + i
+ + ": haveState=" + r.haveState
+ + " stateNotNeeded=" + r.stateNotNeeded
+ + " finishing=" + r.finishing
+ + " state=" + r.state, here);
+ }
+ if (!r.finishing) {
+ Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
+ EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
+ r.userId, System.identityHashCode(r),
+ r.task.taskId, r.shortComponentName,
+ "proc died without state saved");
+ }
+ removeActivityFromHistoryLocked(r);
+
+ } else {
+ // We have the current state for this activity, so
+ // it can be restarted later when needed.
+ if (localLOGV) Slog.v(
+ TAG, "Keeping entry, setting app to null");
+ if (r.visible) {
+ hasVisibleActivities = true;
+ }
+ r.app = null;
+ r.nowVisible = false;
+ if (!r.haveState) {
+ if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
+ "App died, clearing saved state of " + r);
+ r.icicle = null;
+ }
+ }
+
+ r.stack.cleanUpActivityLocked(r, true, true);
+ }
+ }
+
+ return hasVisibleActivities;
}
/**
@@ -4375,7 +4438,7 @@ final class ActivityStack {
return null;
}
- // Remove all of this task's activies starting at the sub task.
+ // Remove all of this task's activities starting at the sub task.
TaskAccessInfo.SubTask subtask = info.subtasks.get(subTaskIndex);
performClearTaskAtIndexLocked(taskId, subtask.index);
return subtask.activity;