Skip to content

Commit 98cfebc

Browse files
author
Dianne Hackborn
committed
Fix issue #5461497: Landed on Welcome screen after a tap on 'Next' in Screen 500
The basic problem was that at some points during setup wizard, this would happen: 1. The app's process is killed. 2. The app's process is restarted, but not to actually resume the setup wizard activity, just to put it in the stopped state. When doing this, the saved state is cleared but the app will never provide a new one. 3. The app's process is killed again. At this point, because the saved state is cleared, the activity is completely removed. 4. Eventually the entire activity stack becomes empty, and a new setup wizard activity needs to be created as the home app. There is a combination of bad stuff going on here. First, why is the process being killed? At this point the setup wizard is the home app, so it shouldn't be killed. There were two reasons why this was happening: - CryptKeeper still was not completely cleanly going away. To fix this, I removed the check in the activity manager to not allow an activity to finish if it is the only activity on the stack and maybe-kindof looks like the home app. This really wasn't necessary (we always take care of starting a new home activity if we find the stack is empty), and outright dangerous with all of these things purporting to be home but not. - There was an issue in computing the oom_adj where the home app would not be marked as "not hidden", and if we had to re-compute its oom adj in the current sequence would then give it an adjustment as a background process... and with all the processes we spin through during boot, it quickly got down to background #16 and killed. Second, what is going on with the state? This is easier, the code in the activity manager to create a new activity but put it in the stopped state was still clearing the saved state. The saved state should only be cleared when going in to the resumed state. When going in to the stopped state, we can just keep holding the same saved state. Change-Id: I7d21cdcfa082d98ca70c79d9923e29605ee4353e
1 parent 0784884 commit 98cfebc

File tree

2 files changed

+90
-40
lines changed

2 files changed

+90
-40
lines changed

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

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ public final class ActivityManagerService extends ActivityManagerNative
165165
static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
166166
static final boolean DEBUG_USER_LEAVING = localLOGV || false;
167167
static final boolean DEBUG_RESULTS = localLOGV || false;
168-
static final boolean DEBUG_BACKUP = localLOGV || true;
168+
static final boolean DEBUG_BACKUP = localLOGV || false;
169169
static final boolean DEBUG_CONFIGURATION = localLOGV || false;
170170
static final boolean DEBUG_POWER = localLOGV || false;
171171
static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
@@ -2607,9 +2607,18 @@ private final void handleAppDiedLocked(ProcessRecord app,
26072607
TAG, "Record #" + i + " " + r + ": app=" + r.app);
26082608
if (r.app == app) {
26092609
if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
2610-
if (localLOGV) Slog.v(
2611-
TAG, "Removing this entry! frozen=" + r.haveState
2612-
+ " finishing=" + r.finishing);
2610+
if (ActivityStack.DEBUG_ADD_REMOVE) {
2611+
RuntimeException here = new RuntimeException("here");
2612+
here.fillInStackTrace();
2613+
Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2614+
+ ": haveState=" + r.haveState
2615+
+ " stateNotNeeded=" + r.stateNotNeeded
2616+
+ " finishing=" + r.finishing
2617+
+ " state=" + r.state, here);
2618+
}
2619+
if (!r.finishing) {
2620+
Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2621+
}
26132622
r.makeFinishing();
26142623
mMainStack.mHistory.remove(i);
26152624
r.takeFromHistory();
@@ -2630,6 +2639,8 @@ private final void handleAppDiedLocked(ProcessRecord app,
26302639
r.app = null;
26312640
r.nowVisible = false;
26322641
if (!r.haveState) {
2642+
if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2643+
"App died, clearing saved state of " + r);
26332644
r.icicle = null;
26342645
}
26352646
}
@@ -4479,7 +4490,7 @@ int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
44794490
}
44804491
}
44814492
if (pi == null) {
4482-
Slog.w(TAG, "No content provider found for: " + name);
4493+
Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
44834494
return -1;
44844495
}
44854496

@@ -4735,7 +4746,7 @@ private void revokeUriPermissionLocked(int callingUid, Uri uri,
47354746
}
47364747
}
47374748
if (pi == null) {
4738-
Slog.w(TAG, "No content provider found for: " + authority);
4749+
Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
47394750
return;
47404751
}
47414752

@@ -4829,7 +4840,8 @@ public void revokeUriPermission(IApplicationThread caller, Uri uri,
48294840
}
48304841
}
48314842
if (pi == null) {
4832-
Slog.w(TAG, "No content provider found for: " + authority);
4843+
Slog.w(TAG, "No content provider found for permission revoke: "
4844+
+ uri.toSafeString());
48334845
return;
48344846
}
48354847

@@ -13054,11 +13066,13 @@ private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
1305413066
if (app.foregroundServices) {
1305513067
// The user is aware of this app, so make it visible.
1305613068
adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13069+
app.hidden = false;
1305713070
app.adjType = "foreground-service";
1305813071
schedGroup = Process.THREAD_GROUP_DEFAULT;
1305913072
} else if (app.forcingToForeground != null) {
1306013073
// The user is aware of this app, so make it visible.
1306113074
adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13075+
app.hidden = false;
1306213076
app.adjType = "force-foreground";
1306313077
app.adjSource = app.forcingToForeground;
1306413078
schedGroup = Process.THREAD_GROUP_DEFAULT;
@@ -13069,6 +13083,7 @@ private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
1306913083
// We don't want to kill the current heavy-weight process.
1307013084
adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
1307113085
schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13086+
app.hidden = false;
1307213087
app.adjType = "heavy";
1307313088
}
1307413089

@@ -13077,11 +13092,13 @@ private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
1307713092
// home app, so we don't want to let it go into the background.
1307813093
adj = ProcessList.HOME_APP_ADJ;
1307913094
schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13095+
app.hidden = false;
1308013096
app.adjType = "home";
1308113097
}
13082-
13083-
//Slog.i(TAG, "OOM " + app + ": initial adj=" + adj);
13084-
13098+
13099+
if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
13100+
+ " reason=" + app.adjType);
13101+
1308513102
// By default, we use the computed adjustment. It may be changed if
1308613103
// there are applications dependent on our services or providers, but
1308713104
// this gives us a baseline and makes sure we don't get into an
@@ -13108,7 +13125,7 @@ private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
1310813125
while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
1310913126
ServiceRecord s = jt.next();
1311013127
if (s.startRequested) {
13111-
if (app.hasShownUi) {
13128+
if (app.hasShownUi && app != mHomeProcess) {
1311213129
// If this process has shown some UI, let it immediately
1311313130
// go to the LRU list because it may be pretty heavy with
1311413131
// UI stuff. We'll tag it with a label just to help
@@ -13169,14 +13186,15 @@ private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
1316913186
if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
1317013187
// Not doing bind OOM management, so treat
1317113188
// this guy more like a started service.
13172-
if (app.hasShownUi) {
13189+
if (app.hasShownUi && app != mHomeProcess) {
1317313190
// If this process has shown some UI, let it immediately
1317413191
// go to the LRU list because it may be pretty heavy with
1317513192
// UI stuff. We'll tag it with a label just to help
1317613193
// debug and understand what is going on.
1317713194
if (adj > clientAdj) {
1317813195
adjType = "bound-bg-ui-services";
1317913196
}
13197+
app.hidden = false;
1318013198
clientAdj = adj;
1318113199
} else {
1318213200
if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
@@ -13200,7 +13218,8 @@ private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
1320013218
// about letting this process get into the LRU
1320113219
// list to be killed and restarted if needed for
1320213220
// memory.
13203-
if (app.hasShownUi && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13221+
if (app.hasShownUi && app != mHomeProcess
13222+
&& clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
1320413223
adjType = "bound-bg-ui-services";
1320513224
} else {
1320613225
if ((cr.flags&(Context.BIND_ABOVE_CLIENT
@@ -13294,7 +13313,8 @@ private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
1329413313
int clientAdj = computeOomAdjLocked(
1329513314
client, myHiddenAdj, TOP_APP, true);
1329613315
if (adj > clientAdj) {
13297-
if (app.hasShownUi && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13316+
if (app.hasShownUi && app != mHomeProcess
13317+
&& clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
1329813318
app.adjType = "bg-ui-provider";
1329913319
} else {
1330013320
adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ

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

Lines changed: 56 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ final class ActivityStack {
8787
static final boolean DEBUG_TASKS = ActivityManagerService.DEBUG_TASKS;
8888

8989
static final boolean DEBUG_STATES = false;
90+
static final boolean DEBUG_ADD_REMOVE = false;
91+
static final boolean DEBUG_SAVED_STATE = false;
9092

9193
static final boolean VALIDATE_TOKENS = ActivityManagerService.VALIDATE_TOKENS;
9294

@@ -653,6 +655,9 @@ final boolean realStartActivityLocked(ActivityRecord r,
653655
}
654656
completeResumeLocked(r);
655657
checkReadyForSleepLocked();
658+
if (DEBUG_SAVED_STATE) Slog.i(TAG, "Launch completed; removing icicle of " + r.icicle);
659+
r.icicle = null;
660+
r.haveState = false;
656661
} else {
657662
// This activity is not starting in the resumed state... which
658663
// should look like we asked it to pause+stop (but remain visible),
@@ -664,9 +669,6 @@ final boolean realStartActivityLocked(ActivityRecord r,
664669
r.stopped = true;
665670
}
666671

667-
r.icicle = null;
668-
r.haveState = false;
669-
670672
// Launch the new version setup screen if needed. We do this -after-
671673
// launching the initial activity (that is, home), so that it can have
672674
// a chance to initialize itself while in the background, making the
@@ -936,6 +938,7 @@ final void activityPaused(IBinder token, boolean timeout) {
936938

937939
final void activityStoppedLocked(ActivityRecord r, Bundle icicle, Bitmap thumbnail,
938940
CharSequence description) {
941+
if (DEBUG_SAVED_STATE) Slog.i(TAG, "Saving icicle of " + r + ": " + icicle);
939942
r.icicle = icicle;
940943
r.haveState = true;
941944
r.updateThumbnail(thumbnail, description);
@@ -1544,6 +1547,7 @@ final boolean resumeTopActivityLocked(ActivityRecord prev) {
15441547
}
15451548

15461549
// Didn't need to use the icicle, and it is now out of date.
1550+
if (DEBUG_SAVED_STATE) Slog.i(TAG, "Resumed activity; didn't need icicle of: " + next);
15471551
next.icicle = null;
15481552
next.haveState = false;
15491553
next.stopped = false;
@@ -1590,6 +1594,12 @@ private final void startActivityLocked(ActivityRecord r, boolean newTask,
15901594
// get started when the user navigates back to it.
15911595
addPos = i+1;
15921596
if (!startIt) {
1597+
if (DEBUG_ADD_REMOVE) {
1598+
RuntimeException here = new RuntimeException("here");
1599+
here.fillInStackTrace();
1600+
Slog.i(TAG, "Adding activity " + r + " to stack at " + addPos,
1601+
here);
1602+
}
15931603
mHistory.add(addPos, r);
15941604
r.putInHistory();
15951605
mService.mWindowManager.addAppToken(addPos, r, r.task.taskId,
@@ -1622,6 +1632,11 @@ private final void startActivityLocked(ActivityRecord r, boolean newTask,
16221632
}
16231633

16241634
// Slot the activity into the history stack and proceed
1635+
if (DEBUG_ADD_REMOVE) {
1636+
RuntimeException here = new RuntimeException("here");
1637+
here.fillInStackTrace();
1638+
Slog.i(TAG, "Adding activity " + r + " to stack at " + addPos, here);
1639+
}
16251640
mHistory.add(addPos, r);
16261641
r.putInHistory();
16271642
r.frontOfTask = newTask;
@@ -1818,6 +1833,12 @@ private final ActivityRecord resetTaskIfNeededLocked(ActivityRecord taskTop,
18181833
+ " out to target's task " + target.task);
18191834
p.setTask(target.task, curThumbHolder, false);
18201835
curThumbHolder = p.thumbHolder;
1836+
if (DEBUG_ADD_REMOVE) {
1837+
RuntimeException here = new RuntimeException("here");
1838+
here.fillInStackTrace();
1839+
Slog.i(TAG, "Removing and adding activity " + p + " to stack at "
1840+
+ dstPos, here);
1841+
}
18211842
mHistory.remove(srcPos);
18221843
mHistory.add(dstPos, p);
18231844
mService.mWindowManager.moveAppToken(dstPos, p);
@@ -1945,6 +1966,12 @@ private final ActivityRecord resetTaskIfNeededLocked(ActivityRecord taskTop,
19451966
} else {
19461967
lastReparentPos--;
19471968
}
1969+
if (DEBUG_ADD_REMOVE) {
1970+
RuntimeException here = new RuntimeException("here");
1971+
here.fillInStackTrace();
1972+
Slog.i(TAG, "Removing and adding activity " + p + " to stack at "
1973+
+ lastReparentPos, here);
1974+
}
19481975
mHistory.remove(srcPos);
19491976
p.setTask(task, null, false);
19501977
mHistory.add(lastReparentPos, p);
@@ -2143,6 +2170,12 @@ private final ActivityRecord moveActivityToFrontLocked(int where) {
21432170
ActivityRecord newTop = mHistory.remove(where);
21442171
int top = mHistory.size();
21452172
ActivityRecord oldTop = mHistory.get(top-1);
2173+
if (DEBUG_ADD_REMOVE) {
2174+
RuntimeException here = new RuntimeException("here");
2175+
here.fillInStackTrace();
2176+
Slog.i(TAG, "Removing and adding activity " + newTop + " to stack at "
2177+
+ top, here);
2178+
}
21462179
mHistory.add(top, newTop);
21472180
oldTop.frontOfTask = false;
21482181
newTop.frontOfTask = true;
@@ -2183,7 +2216,7 @@ final int startActivityLocked(IApplicationThread caller,
21832216
if (resultTo != null) {
21842217
int index = indexOfTokenLocked(resultTo);
21852218
if (DEBUG_RESULTS) Slog.v(
2186-
TAG, "Sending result to " + resultTo + " (index " + index + ")");
2219+
TAG, "Will send result to " + resultTo + " (index " + index + ")");
21872220
if (index >= 0) {
21882221
sourceRecord = mHistory.get(index);
21892222
if (requestCode >= 0 && !sourceRecord.finishing) {
@@ -3279,34 +3312,15 @@ final ActivityRecord activityIdleInternal(IBinder token, boolean fromTimeout,
32793312
*/
32803313
final boolean requestFinishActivityLocked(IBinder token, int resultCode,
32813314
Intent resultData, String reason) {
3282-
if (DEBUG_RESULTS) Slog.v(
3283-
TAG, "Finishing activity: token=" + token
3284-
+ ", result=" + resultCode + ", data=" + resultData);
3285-
32863315
int index = indexOfTokenLocked(token);
3316+
if (DEBUG_RESULTS) Slog.v(
3317+
TAG, "Finishing activity @" + index + ": token=" + token
3318+
+ ", result=" + resultCode + ", data=" + resultData);
32873319
if (index < 0) {
32883320
return false;
32893321
}
32903322
ActivityRecord r = mHistory.get(index);
32913323

3292-
// Is this the last activity left?
3293-
boolean lastActivity = true;
3294-
for (int i=mHistory.size()-1; i>=0; i--) {
3295-
ActivityRecord p = mHistory.get(i);
3296-
if (!p.finishing && p != r) {
3297-
lastActivity = false;
3298-
break;
3299-
}
3300-
}
3301-
3302-
// If this is the last activity, but it is the home activity, then
3303-
// just don't finish it.
3304-
if (lastActivity) {
3305-
if (r.intent.hasCategory(Intent.CATEGORY_HOME)) {
3306-
return false;
3307-
}
3308-
}
3309-
33103324
finishActivityLocked(r, index, resultCode, resultData, reason);
33113325
return true;
33123326
}
@@ -3538,6 +3552,11 @@ final void cleanUpActivityLocked(ActivityRecord r, boolean cleanServices,
35383552
private final void removeActivityFromHistoryLocked(ActivityRecord r) {
35393553
if (r.state != ActivityState.DESTROYED) {
35403554
r.makeFinishing();
3555+
if (DEBUG_ADD_REMOVE) {
3556+
RuntimeException here = new RuntimeException("here");
3557+
here.fillInStackTrace();
3558+
Slog.i(TAG, "Removing activity " + r + " from stack");
3559+
}
35413560
mHistory.remove(r);
35423561
r.takeFromHistory();
35433562
if (DEBUG_STATES) Slog.v(TAG, "Moving to DESTROYED: " + r
@@ -3769,6 +3788,11 @@ final void moveTaskToFrontLocked(TaskRecord tr, ActivityRecord reason) {
37693788
TAG, "At " + pos + " ckp " + r.task + ": " + r);
37703789
if (r.task.taskId == task) {
37713790
if (localLOGV) Slog.v(TAG, "Removing and adding at " + top);
3791+
if (DEBUG_ADD_REMOVE) {
3792+
RuntimeException here = new RuntimeException("here");
3793+
here.fillInStackTrace();
3794+
Slog.i(TAG, "Removing and adding activity " + r + " to stack at " + top, here);
3795+
}
37723796
mHistory.remove(pos);
37733797
mHistory.add(top, r);
37743798
moved.add(0, r);
@@ -3858,6 +3882,12 @@ final boolean moveTaskToBackLocked(int task, ActivityRecord reason) {
38583882
TAG, "At " + pos + " ckp " + r.task + ": " + r);
38593883
if (r.task.taskId == task) {
38603884
if (localLOGV) Slog.v(TAG, "Removing and adding at " + (N-1));
3885+
if (DEBUG_ADD_REMOVE) {
3886+
RuntimeException here = new RuntimeException("here");
3887+
here.fillInStackTrace();
3888+
Slog.i(TAG, "Removing and adding activity " + r + " to stack at "
3889+
+ bottom, here);
3890+
}
38613891
mHistory.remove(pos);
38623892
mHistory.add(bottom, r);
38633893
moved.add(r);

0 commit comments

Comments
 (0)