diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 55fb371d1753f..0d6f405136dd5 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -165,7 +165,7 @@ public final class ActivityManagerService extends ActivityManagerNative static final boolean DEBUG_URI_PERMISSION = localLOGV || false; static final boolean DEBUG_USER_LEAVING = localLOGV || false; static final boolean DEBUG_RESULTS = localLOGV || false; - static final boolean DEBUG_BACKUP = localLOGV || true; + static final boolean DEBUG_BACKUP = localLOGV || false; static final boolean DEBUG_CONFIGURATION = localLOGV || false; static final boolean DEBUG_POWER = localLOGV || false; static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; @@ -2607,9 +2607,18 @@ public final class ActivityManagerService extends ActivityManagerNative TAG, "Record #" + i + " " + r + ": app=" + r.app); if (r.app == app) { if ((!r.haveState && !r.stateNotNeeded) || r.finishing) { - if (localLOGV) Slog.v( - TAG, "Removing this entry! frozen=" + r.haveState - + " finishing=" + 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"); + } r.makeFinishing(); mMainStack.mHistory.remove(i); r.takeFromHistory(); @@ -2630,6 +2639,8 @@ public final class ActivityManagerService extends ActivityManagerNative 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; } } @@ -4479,7 +4490,7 @@ public final class ActivityManagerService extends ActivityManagerNative } } if (pi == null) { - Slog.w(TAG, "No content provider found for: " + name); + Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); return -1; } @@ -4735,7 +4746,7 @@ public final class ActivityManagerService extends ActivityManagerNative } } if (pi == null) { - Slog.w(TAG, "No content provider found for: " + authority); + Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); return; } @@ -4829,7 +4840,8 @@ public final class ActivityManagerService extends ActivityManagerNative } } if (pi == null) { - Slog.w(TAG, "No content provider found for: " + authority); + Slog.w(TAG, "No content provider found for permission revoke: " + + uri.toSafeString()); return; } @@ -13054,11 +13066,13 @@ public final class ActivityManagerService extends ActivityManagerNative if (app.foregroundServices) { // The user is aware of this app, so make it visible. adj = ProcessList.PERCEPTIBLE_APP_ADJ; + app.hidden = false; app.adjType = "foreground-service"; schedGroup = Process.THREAD_GROUP_DEFAULT; } else if (app.forcingToForeground != null) { // The user is aware of this app, so make it visible. adj = ProcessList.PERCEPTIBLE_APP_ADJ; + app.hidden = false; app.adjType = "force-foreground"; app.adjSource = app.forcingToForeground; schedGroup = Process.THREAD_GROUP_DEFAULT; @@ -13069,6 +13083,7 @@ public final class ActivityManagerService extends ActivityManagerNative // We don't want to kill the current heavy-weight process. adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; + app.hidden = false; app.adjType = "heavy"; } @@ -13077,11 +13092,13 @@ public final class ActivityManagerService extends ActivityManagerNative // home app, so we don't want to let it go into the background. adj = ProcessList.HOME_APP_ADJ; schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; + app.hidden = false; app.adjType = "home"; } - - //Slog.i(TAG, "OOM " + app + ": initial adj=" + adj); - + + if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj + + " reason=" + app.adjType); + // By default, we use the computed adjustment. It may be changed if // there are applications dependent on our services or providers, but // this gives us a baseline and makes sure we don't get into an @@ -13108,7 +13125,7 @@ public final class ActivityManagerService extends ActivityManagerNative while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) { ServiceRecord s = jt.next(); if (s.startRequested) { - if (app.hasShownUi) { + if (app.hasShownUi && app != mHomeProcess) { // If this process has shown some UI, let it immediately // go to the LRU list because it may be pretty heavy with // UI stuff. We'll tag it with a label just to help @@ -13169,7 +13186,7 @@ public final class ActivityManagerService extends ActivityManagerNative if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { // Not doing bind OOM management, so treat // this guy more like a started service. - if (app.hasShownUi) { + if (app.hasShownUi && app != mHomeProcess) { // If this process has shown some UI, let it immediately // go to the LRU list because it may be pretty heavy with // UI stuff. We'll tag it with a label just to help @@ -13177,6 +13194,7 @@ public final class ActivityManagerService extends ActivityManagerNative if (adj > clientAdj) { adjType = "bound-bg-ui-services"; } + app.hidden = false; clientAdj = adj; } else { if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) { @@ -13200,7 +13218,8 @@ public final class ActivityManagerService extends ActivityManagerNative // about letting this process get into the LRU // list to be killed and restarted if needed for // memory. - if (app.hasShownUi && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { + if (app.hasShownUi && app != mHomeProcess + && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { adjType = "bound-bg-ui-services"; } else { if ((cr.flags&(Context.BIND_ABOVE_CLIENT @@ -13294,7 +13313,8 @@ public final class ActivityManagerService extends ActivityManagerNative int clientAdj = computeOomAdjLocked( client, myHiddenAdj, TOP_APP, true); if (adj > clientAdj) { - if (app.hasShownUi && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { + if (app.hasShownUi && app != mHomeProcess + && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { app.adjType = "bg-ui-provider"; } else { adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index 1aed7fe0a1d88..28c3baeb7b635 100644 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -87,6 +87,8 @@ final class ActivityStack { static final boolean DEBUG_TASKS = ActivityManagerService.DEBUG_TASKS; static final boolean DEBUG_STATES = false; + static final boolean DEBUG_ADD_REMOVE = false; + static final boolean DEBUG_SAVED_STATE = false; static final boolean VALIDATE_TOKENS = ActivityManagerService.VALIDATE_TOKENS; @@ -653,6 +655,9 @@ final class ActivityStack { } completeResumeLocked(r); checkReadyForSleepLocked(); + if (DEBUG_SAVED_STATE) Slog.i(TAG, "Launch completed; removing icicle of " + r.icicle); + r.icicle = null; + r.haveState = false; } else { // This activity is not starting in the resumed state... which // should look like we asked it to pause+stop (but remain visible), @@ -664,9 +669,6 @@ final class ActivityStack { r.stopped = true; } - r.icicle = null; - r.haveState = false; - // Launch the new version setup screen if needed. We do this -after- // launching the initial activity (that is, home), so that it can have // a chance to initialize itself while in the background, making the @@ -936,6 +938,7 @@ final class ActivityStack { final void activityStoppedLocked(ActivityRecord r, Bundle icicle, Bitmap thumbnail, CharSequence description) { + if (DEBUG_SAVED_STATE) Slog.i(TAG, "Saving icicle of " + r + ": " + icicle); r.icicle = icicle; r.haveState = true; r.updateThumbnail(thumbnail, description); @@ -1544,6 +1547,7 @@ final class ActivityStack { } // Didn't need to use the icicle, and it is now out of date. + if (DEBUG_SAVED_STATE) Slog.i(TAG, "Resumed activity; didn't need icicle of: " + next); next.icicle = null; next.haveState = false; next.stopped = false; @@ -1590,6 +1594,12 @@ final class ActivityStack { // get started when the user navigates back to it. addPos = i+1; if (!startIt) { + if (DEBUG_ADD_REMOVE) { + RuntimeException here = new RuntimeException("here"); + here.fillInStackTrace(); + Slog.i(TAG, "Adding activity " + r + " to stack at " + addPos, + here); + } mHistory.add(addPos, r); r.putInHistory(); mService.mWindowManager.addAppToken(addPos, r, r.task.taskId, @@ -1622,6 +1632,11 @@ final class ActivityStack { } // Slot the activity into the history stack and proceed + if (DEBUG_ADD_REMOVE) { + RuntimeException here = new RuntimeException("here"); + here.fillInStackTrace(); + Slog.i(TAG, "Adding activity " + r + " to stack at " + addPos, here); + } mHistory.add(addPos, r); r.putInHistory(); r.frontOfTask = newTask; @@ -1818,6 +1833,12 @@ final class ActivityStack { + " out to target's task " + target.task); p.setTask(target.task, curThumbHolder, false); curThumbHolder = p.thumbHolder; + if (DEBUG_ADD_REMOVE) { + RuntimeException here = new RuntimeException("here"); + here.fillInStackTrace(); + Slog.i(TAG, "Removing and adding activity " + p + " to stack at " + + dstPos, here); + } mHistory.remove(srcPos); mHistory.add(dstPos, p); mService.mWindowManager.moveAppToken(dstPos, p); @@ -1945,6 +1966,12 @@ final class ActivityStack { } else { lastReparentPos--; } + if (DEBUG_ADD_REMOVE) { + RuntimeException here = new RuntimeException("here"); + here.fillInStackTrace(); + Slog.i(TAG, "Removing and adding activity " + p + " to stack at " + + lastReparentPos, here); + } mHistory.remove(srcPos); p.setTask(task, null, false); mHistory.add(lastReparentPos, p); @@ -2143,6 +2170,12 @@ final class ActivityStack { ActivityRecord newTop = mHistory.remove(where); int top = mHistory.size(); ActivityRecord oldTop = mHistory.get(top-1); + if (DEBUG_ADD_REMOVE) { + RuntimeException here = new RuntimeException("here"); + here.fillInStackTrace(); + Slog.i(TAG, "Removing and adding activity " + newTop + " to stack at " + + top, here); + } mHistory.add(top, newTop); oldTop.frontOfTask = false; newTop.frontOfTask = true; @@ -2183,7 +2216,7 @@ final class ActivityStack { if (resultTo != null) { int index = indexOfTokenLocked(resultTo); if (DEBUG_RESULTS) Slog.v( - TAG, "Sending result to " + resultTo + " (index " + index + ")"); + TAG, "Will send result to " + resultTo + " (index " + index + ")"); if (index >= 0) { sourceRecord = mHistory.get(index); if (requestCode >= 0 && !sourceRecord.finishing) { @@ -3279,34 +3312,15 @@ final class ActivityStack { */ final boolean requestFinishActivityLocked(IBinder token, int resultCode, Intent resultData, String reason) { - if (DEBUG_RESULTS) Slog.v( - TAG, "Finishing activity: token=" + token - + ", result=" + resultCode + ", data=" + resultData); - int index = indexOfTokenLocked(token); + if (DEBUG_RESULTS) Slog.v( + TAG, "Finishing activity @" + index + ": token=" + token + + ", result=" + resultCode + ", data=" + resultData); if (index < 0) { return false; } ActivityRecord r = mHistory.get(index); - // Is this the last activity left? - boolean lastActivity = true; - for (int i=mHistory.size()-1; i>=0; i--) { - ActivityRecord p = mHistory.get(i); - if (!p.finishing && p != r) { - lastActivity = false; - break; - } - } - - // If this is the last activity, but it is the home activity, then - // just don't finish it. - if (lastActivity) { - if (r.intent.hasCategory(Intent.CATEGORY_HOME)) { - return false; - } - } - finishActivityLocked(r, index, resultCode, resultData, reason); return true; } @@ -3538,6 +3552,11 @@ final class ActivityStack { private final void removeActivityFromHistoryLocked(ActivityRecord r) { if (r.state != ActivityState.DESTROYED) { 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 @@ -3769,6 +3788,11 @@ final class ActivityStack { TAG, "At " + pos + " ckp " + r.task + ": " + r); if (r.task.taskId == task) { if (localLOGV) Slog.v(TAG, "Removing and adding at " + top); + if (DEBUG_ADD_REMOVE) { + RuntimeException here = new RuntimeException("here"); + here.fillInStackTrace(); + Slog.i(TAG, "Removing and adding activity " + r + " to stack at " + top, here); + } mHistory.remove(pos); mHistory.add(top, r); moved.add(0, r); @@ -3858,6 +3882,12 @@ final class ActivityStack { TAG, "At " + pos + " ckp " + r.task + ": " + r); if (r.task.taskId == task) { if (localLOGV) Slog.v(TAG, "Removing and adding at " + (N-1)); + if (DEBUG_ADD_REMOVE) { + RuntimeException here = new RuntimeException("here"); + here.fillInStackTrace(); + Slog.i(TAG, "Removing and adding activity " + r + " to stack at " + + bottom, here); + } mHistory.remove(pos); mHistory.add(bottom, r); moved.add(r);