Skip to content

Commit cc5a055

Browse files
author
Dianne Hackborn
committed
Fix issue #7226101: Secure image capture takes 5 seconds to start
Mostly (turned off) debug output. Main fix is to resume the next activity if we are pausing while sleeping and the top activity is not the now pausing activity. Also helped things by fixing a problem where removing a task would leave around dead destroy timeout messages. Change-Id: I9d550c216b4d7e2afe3d93553bb680cec41e2ed1
1 parent 933a754 commit cc5a055

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)