Skip to content

Commit 6f354ed

Browse files
Dianne HackbornAndroid (Google) Code Review
authored andcommitted
Merge "Fix issue #7226101: Secure image capture takes 5 seconds to start" into jb-mr1-dev
2 parents 046cff1 + cc5a055 commit 6f354ed

File tree

2 files changed

+113
-101
lines changed

2 files changed

+113
-101
lines changed

services/java/com/android/server/am/ActivityManagerService.java

Lines changed: 10 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ public final class ActivityManagerService extends ActivityManagerNative
181181
static final boolean DEBUG_VISBILITY = localLOGV || false;
182182
static final boolean DEBUG_PROCESSES = localLOGV || false;
183183
static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
184+
static final boolean DEBUG_CLEANUP = localLOGV || false;
184185
static final boolean DEBUG_PROVIDER = localLOGV || false;
185186
static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
186187
static final boolean DEBUG_USER_LEAVING = localLOGV || false;
@@ -1968,7 +1969,7 @@ final ProcessRecord startProcessLocked(String processName,
19681969
} else {
19691970
// An application record is attached to a previous process,
19701971
// clean it up now.
1971-
if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
1972+
if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
19721973
handleAppDiedLocked(app, true, true);
19731974
}
19741975
}
@@ -2925,69 +2926,16 @@ private final void handleAppDiedLocked(ProcessRecord app,
29252926

29262927
// Just in case...
29272928
if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2928-
if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2929+
if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG,
2930+
"App died while pausing: " + mMainStack.mPausingActivity);
29292931
mMainStack.mPausingActivity = null;
29302932
}
29312933
if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
29322934
mMainStack.mLastPausedActivity = null;
29332935
}
29342936

29352937
// Remove this application's activities from active lists.
2936-
mMainStack.removeHistoryRecordsForAppLocked(app);
2937-
2938-
boolean atTop = true;
2939-
boolean hasVisibleActivities = false;
2940-
2941-
// Clean out the history list.
2942-
int i = mMainStack.mHistory.size();
2943-
if (localLOGV) Slog.v(
2944-
TAG, "Removing app " + app + " from history with " + i + " entries");
2945-
while (i > 0) {
2946-
i--;
2947-
ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2948-
if (localLOGV) Slog.v(
2949-
TAG, "Record #" + i + " " + r + ": app=" + r.app);
2950-
if (r.app == app) {
2951-
if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
2952-
if (ActivityStack.DEBUG_ADD_REMOVE) {
2953-
RuntimeException here = new RuntimeException("here");
2954-
here.fillInStackTrace();
2955-
Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2956-
+ ": haveState=" + r.haveState
2957-
+ " stateNotNeeded=" + r.stateNotNeeded
2958-
+ " finishing=" + r.finishing
2959-
+ " state=" + r.state, here);
2960-
}
2961-
if (!r.finishing) {
2962-
Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2963-
EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2964-
r.userId, System.identityHashCode(r),
2965-
r.task.taskId, r.shortComponentName,
2966-
"proc died without state saved");
2967-
}
2968-
mMainStack.removeActivityFromHistoryLocked(r);
2969-
2970-
} else {
2971-
// We have the current state for this activity, so
2972-
// it can be restarted later when needed.
2973-
if (localLOGV) Slog.v(
2974-
TAG, "Keeping entry, setting app to null");
2975-
if (r.visible) {
2976-
hasVisibleActivities = true;
2977-
}
2978-
r.app = null;
2979-
r.nowVisible = false;
2980-
if (!r.haveState) {
2981-
if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2982-
"App died, clearing saved state of " + r);
2983-
r.icicle = null;
2984-
}
2985-
}
2986-
2987-
r.stack.cleanUpActivityLocked(r, true, true);
2988-
}
2989-
atTop = false;
2990-
}
2938+
boolean hasVisibleActivities = mMainStack.removeHistoryRecordsForAppLocked(app);
29912939

29922940
app.activities.clear();
29932941

@@ -3053,7 +3001,7 @@ final void appDiedLocked(ProcessRecord app, int pid,
30533001
+ ") has died.");
30543002
}
30553003
EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3056-
if (localLOGV) Slog.v(
3004+
if (DEBUG_CLEANUP) Slog.v(
30573005
TAG, "Dying app: " + app + ", pid: " + pid
30583006
+ ", thread: " + thread.asBinder());
30593007
boolean doLowMem = app.instrumentationClass == null;
@@ -10757,7 +10705,8 @@ private final void cleanUpApplicationRecordLocked(ProcessRecord app,
1075710705

1075810706
// If the app is undergoing backup, tell the backup manager about it
1075910707
if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10760-
if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
10708+
if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
10709+
+ mBackupTarget.appInfo + " died during backup");
1076110710
try {
1076210711
IBackupManager bm = IBackupManager.Stub.asInterface(
1076310712
ServiceManager.getService(Context.BACKUP_SERVICE));
@@ -10783,7 +10732,7 @@ private final void cleanUpApplicationRecordLocked(ProcessRecord app,
1078310732
}
1078410733

1078510734
if (!app.persistent || app.isolated) {
10786-
if (DEBUG_PROCESSES) Slog.v(TAG,
10735+
if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
1078710736
"Removing non-persistent process during cleanup: " + app);
1078810737
mProcessNames.remove(app.processName, app.uid);
1078910738
mIsolatedProcesses.remove(app.uid);
@@ -10801,7 +10750,7 @@ private final void cleanUpApplicationRecordLocked(ProcessRecord app,
1080110750
restart = true;
1080210751
}
1080310752
}
10804-
if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10753+
if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
1080510754
"Clean-up removing on hold: " + app);
1080610755
mProcessesOnHold.remove(app);
1080710756

services/java/com/android/server/am/ActivityStack.java

Lines changed: 103 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ final class ActivityStack {
8181
static final boolean DEBUG_RESULTS = ActivityManagerService.DEBUG_RESULTS;
8282
static final boolean DEBUG_CONFIGURATION = ActivityManagerService.DEBUG_CONFIGURATION;
8383
static final boolean DEBUG_TASKS = ActivityManagerService.DEBUG_TASKS;
84+
static final boolean DEBUG_CLEANUP = ActivityManagerService.DEBUG_CLEANUP;
8485

8586
static final boolean DEBUG_STATES = false;
8687
static final boolean DEBUG_ADD_REMOVE = false;
@@ -1142,9 +1143,13 @@ private final void completePauseLocked() {
11421143
resumeTopActivityLocked(prev);
11431144
} else {
11441145
checkReadyForSleepLocked();
1145-
if (topRunningActivityLocked(null) == null) {
1146-
// If there are no more activities available to run, then
1147-
// do resume anyway to start something.
1146+
ActivityRecord top = topRunningActivityLocked(null);
1147+
if (top == null || (prev != null && top != prev)) {
1148+
// If there are no more activities available to run,
1149+
// do resume anyway to start something. Also if the top
1150+
// activity on the stack is not the just paused activity,
1151+
// we need to go ahead and resume it to ensure we complete
1152+
// an in-flight app switch.
11481153
resumeTopActivityLocked(null);
11491154
}
11501155
}
@@ -1461,7 +1466,8 @@ final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
14611466
// If we are currently pausing an activity, then don't do anything
14621467
// until that is done.
14631468
if (mPausingActivity != null) {
1464-
if (DEBUG_SWITCH) Slog.v(TAG, "Skip resume: pausing=" + mPausingActivity);
1469+
if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(TAG,
1470+
"Skip resume: pausing=" + mPausingActivity);
14651471
return false;
14661472
}
14671473

@@ -3862,6 +3868,7 @@ final void cleanUpActivityLocked(ActivityRecord r, boolean cleanServices,
38623868
if (setState) {
38633869
if (DEBUG_STATES) Slog.v(TAG, "Moving to DESTROYED: " + r + " (cleaning up)");
38643870
r.state = ActivityState.DESTROYED;
3871+
r.app = null;
38653872
}
38663873

38673874
// Make sure this record is no longer in the pending finishes list.
@@ -3905,26 +3912,26 @@ private void removeTimeoutsForActivityLocked(ActivityRecord r) {
39053912
}
39063913

39073914
final void removeActivityFromHistoryLocked(ActivityRecord r) {
3908-
if (r.state != ActivityState.DESTROYED) {
3909-
finishActivityResultsLocked(r, Activity.RESULT_CANCELED, null);
3910-
r.makeFinishing();
3911-
if (DEBUG_ADD_REMOVE) {
3912-
RuntimeException here = new RuntimeException("here");
3913-
here.fillInStackTrace();
3914-
Slog.i(TAG, "Removing activity " + r + " from stack");
3915-
}
3916-
mHistory.remove(r);
3917-
r.takeFromHistory();
3918-
if (DEBUG_STATES) Slog.v(TAG, "Moving to DESTROYED: " + r
3919-
+ " (removed from history)");
3920-
r.state = ActivityState.DESTROYED;
3921-
mService.mWindowManager.removeAppToken(r.appToken);
3922-
if (VALIDATE_TOKENS) {
3923-
validateAppTokensLocked();
3924-
}
3925-
cleanUpActivityServicesLocked(r);
3926-
r.removeUriPermissionsLocked();
3915+
finishActivityResultsLocked(r, Activity.RESULT_CANCELED, null);
3916+
r.makeFinishing();
3917+
if (DEBUG_ADD_REMOVE) {
3918+
RuntimeException here = new RuntimeException("here");
3919+
here.fillInStackTrace();
3920+
Slog.i(TAG, "Removing activity " + r + " from stack");
3921+
}
3922+
mHistory.remove(r);
3923+
r.takeFromHistory();
3924+
removeTimeoutsForActivityLocked(r);
3925+
if (DEBUG_STATES) Slog.v(TAG, "Moving to DESTROYED: " + r
3926+
+ " (removed from history)");
3927+
r.state = ActivityState.DESTROYED;
3928+
r.app = null;
3929+
mService.mWindowManager.removeAppToken(r.appToken);
3930+
if (VALIDATE_TOKENS) {
3931+
validateAppTokensLocked();
39273932
}
3933+
cleanUpActivityServicesLocked(r);
3934+
r.removeUriPermissionsLocked();
39283935
}
39293936

39303937
/**
@@ -3992,19 +3999,19 @@ final void destroyActivitiesLocked(ProcessRecord owner, boolean oomAdj, String r
39923999
*/
39934000
final boolean destroyActivityLocked(ActivityRecord r,
39944001
boolean removeFromApp, boolean oomAdj, String reason) {
3995-
if (DEBUG_SWITCH) Slog.v(
4002+
if (DEBUG_SWITCH || DEBUG_CLEANUP) Slog.v(
39964003
TAG, "Removing activity from " + reason + ": token=" + r
39974004
+ ", app=" + (r.app != null ? r.app.processName : "(null)"));
39984005
EventLog.writeEvent(EventLogTags.AM_DESTROY_ACTIVITY,
39994006
r.userId, System.identityHashCode(r),
40004007
r.task.taskId, r.shortComponentName, reason);
40014008

40024009
boolean removedFromHistory = false;
4003-
4010+
40044011
cleanUpActivityLocked(r, false, false);
40054012

40064013
final boolean hadApp = r.app != null;
4007-
4014+
40084015
if (hadApp) {
40094016
if (removeFromApp) {
40104017
int idx = r.app.activities.indexOf(r);
@@ -4040,7 +4047,6 @@ final boolean destroyActivityLocked(ActivityRecord r,
40404047
}
40414048
}
40424049

4043-
r.app = null;
40444050
r.nowVisible = false;
40454051

40464052
// If the activity is finishing, we need to wait on removing it
@@ -4061,6 +4067,7 @@ final boolean destroyActivityLocked(ActivityRecord r,
40614067
if (DEBUG_STATES) Slog.v(TAG, "Moving to DESTROYED: " + r
40624068
+ " (destroy skipped)");
40634069
r.state = ActivityState.DESTROYED;
4070+
r.app = null;
40644071
}
40654072
} else {
40664073
// remove this record from the history.
@@ -4071,6 +4078,7 @@ final boolean destroyActivityLocked(ActivityRecord r,
40714078
if (DEBUG_STATES) Slog.v(TAG, "Moving to DESTROYED: " + r
40724079
+ " (no app)");
40734080
r.state = ActivityState.DESTROYED;
4081+
r.app = null;
40744082
}
40754083
}
40764084

@@ -4106,30 +4114,85 @@ final void activityDestroyed(IBinder token) {
41064114
}
41074115
}
41084116

4109-
private void removeHistoryRecordsForAppLocked(ArrayList list, ProcessRecord app) {
4117+
private void removeHistoryRecordsForAppLocked(ArrayList list, ProcessRecord app,
4118+
String listName) {
41104119
int i = list.size();
4111-
if (localLOGV) Slog.v(
4112-
TAG, "Removing app " + app + " from list " + list
4120+
if (DEBUG_CLEANUP) Slog.v(
4121+
TAG, "Removing app " + app + " from list " + listName
41134122
+ " with " + i + " entries");
41144123
while (i > 0) {
41154124
i--;
41164125
ActivityRecord r = (ActivityRecord)list.get(i);
4117-
if (localLOGV) Slog.v(
4118-
TAG, "Record #" + i + " " + r + ": app=" + r.app);
4126+
if (DEBUG_CLEANUP) Slog.v(TAG, "Record #" + i + " " + r);
41194127
if (r.app == app) {
4120-
if (localLOGV) Slog.v(TAG, "Removing this entry!");
4128+
if (DEBUG_CLEANUP) Slog.v(TAG, "---> REMOVING this entry!");
41214129
list.remove(i);
41224130
removeTimeoutsForActivityLocked(r);
41234131
}
41244132
}
41254133
}
41264134

4127-
void removeHistoryRecordsForAppLocked(ProcessRecord app) {
4128-
removeHistoryRecordsForAppLocked(mLRUActivities, app);
4129-
removeHistoryRecordsForAppLocked(mStoppingActivities, app);
4130-
removeHistoryRecordsForAppLocked(mGoingToSleepActivities, app);
4131-
removeHistoryRecordsForAppLocked(mWaitingVisibleActivities, app);
4132-
removeHistoryRecordsForAppLocked(mFinishingActivities, app);
4135+
boolean removeHistoryRecordsForAppLocked(ProcessRecord app) {
4136+
removeHistoryRecordsForAppLocked(mLRUActivities, app, "mLRUActivities");
4137+
removeHistoryRecordsForAppLocked(mStoppingActivities, app, "mStoppingActivities");
4138+
removeHistoryRecordsForAppLocked(mGoingToSleepActivities, app, "mGoingToSleepActivities");
4139+
removeHistoryRecordsForAppLocked(mWaitingVisibleActivities, app,
4140+
"mWaitingVisibleActivities");
4141+
removeHistoryRecordsForAppLocked(mFinishingActivities, app, "mFinishingActivities");
4142+
4143+
boolean hasVisibleActivities = false;
4144+
4145+
// Clean out the history list.
4146+
int i = mHistory.size();
4147+
if (DEBUG_CLEANUP) Slog.v(
4148+
TAG, "Removing app " + app + " from history with " + i + " entries");
4149+
while (i > 0) {
4150+
i--;
4151+
ActivityRecord r = (ActivityRecord)mHistory.get(i);
4152+
if (DEBUG_CLEANUP) Slog.v(
4153+
TAG, "Record #" + i + " " + r + ": app=" + r.app);
4154+
if (r.app == app) {
4155+
if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
4156+
if (ActivityStack.DEBUG_ADD_REMOVE || DEBUG_CLEANUP) {
4157+
RuntimeException here = new RuntimeException("here");
4158+
here.fillInStackTrace();
4159+
Slog.i(TAG, "Removing activity " + r + " from stack at " + i
4160+
+ ": haveState=" + r.haveState
4161+
+ " stateNotNeeded=" + r.stateNotNeeded
4162+
+ " finishing=" + r.finishing
4163+
+ " state=" + r.state, here);
4164+
}
4165+
if (!r.finishing) {
4166+
Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
4167+
EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
4168+
r.userId, System.identityHashCode(r),
4169+
r.task.taskId, r.shortComponentName,
4170+
"proc died without state saved");
4171+
}
4172+
removeActivityFromHistoryLocked(r);
4173+
4174+
} else {
4175+
// We have the current state for this activity, so
4176+
// it can be restarted later when needed.
4177+
if (localLOGV) Slog.v(
4178+
TAG, "Keeping entry, setting app to null");
4179+
if (r.visible) {
4180+
hasVisibleActivities = true;
4181+
}
4182+
r.app = null;
4183+
r.nowVisible = false;
4184+
if (!r.haveState) {
4185+
if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
4186+
"App died, clearing saved state of " + r);
4187+
r.icicle = null;
4188+
}
4189+
}
4190+
4191+
r.stack.cleanUpActivityLocked(r, true, true);
4192+
}
4193+
}
4194+
4195+
return hasVisibleActivities;
41334196
}
41344197

41354198
/**
@@ -4375,7 +4438,7 @@ public ActivityRecord removeTaskActivitiesLocked(int taskId, int subTaskIndex,
43754438
return null;
43764439
}
43774440

4378-
// Remove all of this task's activies starting at the sub task.
4441+
// Remove all of this task's activities starting at the sub task.
43794442
TaskAccessInfo.SubTask subtask = info.subtasks.get(subTaskIndex);
43804443
performClearTaskAtIndexLocked(taskId, subtask.index);
43814444
return subtask.activity;

0 commit comments

Comments
 (0)