diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java index 6e50808ae1225..43598954d32c8 100644 --- a/services/java/com/android/server/am/ActivityRecord.java +++ b/services/java/com/android/server/am/ActivityRecord.java @@ -143,9 +143,6 @@ final class ActivityRecord { private boolean inHistory; // are we in the history stack? final ActivityStackSupervisor mStackSupervisor; - /** Launch the home activity rather than the activity at the top of stack */ - boolean mLaunchHomeTaskNext; - void dump(PrintWriter pw, String prefix) { final long now = SystemClock.uptimeMillis(); pw.print(prefix); pw.print("packageName="); pw.print(packageName); @@ -243,6 +240,8 @@ final class ActivityRecord { pw.print(prefix); pw.print("frozenBeforeDestroy="); pw.print(frozenBeforeDestroy); pw.print(" thumbnailNeeded="); pw.print(thumbnailNeeded); pw.print(" forceNewConfig="); pw.println(forceNewConfig); + pw.print(prefix); pw.print("mActivityType="); + pw.println(activityTypeToString(mActivityType)); pw.print(prefix); pw.print("thumbHolder: "); pw.print(Integer.toHexString(System.identityHashCode(thumbHolder))); if (thumbHolder != null) { @@ -1040,6 +1039,15 @@ final class ActivityRecord { return null; } + private String activityTypeToString(int type) { + switch (type) { + case APPLICATION_ACTIVITY_TYPE: return "APPLICATION_ACTIVITY_TYPE"; + case HOME_ACTIVITY_TYPE: return "HOME_ACTIVITY_TYPE"; + case RECENTS_ACTIVITY_TYPE: return "RECENTS_ACTIVITY_TYPE"; + default: return Integer.toString(type); + } + } + @Override public String toString() { if (stringName != null) { diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index 1f64101f8445c..c31c213c02a4f 100644 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -1000,7 +1000,8 @@ final class ActivityStack { boolean behindFullscreen = !mStackSupervisor.isFrontStack(this) && !(forceHomeShown && isHomeStack()); for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { - final ArrayList activities = mTaskHistory.get(taskNdx).mActivities; + final TaskRecord task = mTaskHistory.get(taskNdx); + final ArrayList activities = task.mActivities; for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { final ActivityRecord r = activities.get(activityNdx); if (r.finishing) { @@ -1083,7 +1084,7 @@ final class ActivityStack { // At this point, nothing else needs to be shown if (DEBUG_VISBILITY) Slog.v(TAG, "Fullscreen: at " + r); behindFullscreen = true; - } else if (r.mLaunchHomeTaskNext) { + } else if (task.mOnTopOfHome) { if (DEBUG_VISBILITY) Slog.v(TAG, "Showing home: at " + r); showHomeBehindStack = true; behindFullscreen = true; @@ -1224,7 +1225,7 @@ final class ActivityStack { final TaskRecord nextTask = next.task; final TaskRecord prevTask = prev != null ? prev.task : null; - if (prevTask != null && prev.mLaunchHomeTaskNext && prev.finishing && prev.frontOfTask) { + if (prevTask != null && prevTask.mOnTopOfHome && prev.finishing && prev.frontOfTask) { if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); if (prevTask == nextTask) { ArrayList activities = prevTask.mActivities; @@ -1234,7 +1235,6 @@ final class ActivityStack { // r is usually the same as next, but what if two activities were launched // before prev finished? if (!r.finishing) { - r.mLaunchHomeTaskNext = true; r.frontOfTask = true; break; } @@ -1243,7 +1243,7 @@ final class ActivityStack { // This task is going away but it was supposed to return to the home task. // Now the task above it has to return to the home task instead. final int taskNdx = mTaskHistory.indexOf(prevTask) + 1; - mTaskHistory.get(taskNdx).mActivities.get(0).mLaunchHomeTaskNext = true; + mTaskHistory.get(taskNdx).mOnTopOfHome = true; } else { if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Launching home next"); return mStackSupervisor.resumeHomeActivity(prev); @@ -2933,7 +2933,7 @@ final class ActivityStack { if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) { // Caller wants the home activity moved with it. To accomplish this, // we'll just indicate that this task returns to the home task. - task.mActivities.get(0).mLaunchHomeTaskNext = true; + task.mOnTopOfHome = true; } moveTaskToFrontLocked(task, null, options); return true; @@ -2994,17 +2994,17 @@ final class ActivityStack { * If a watcher is installed, the action is preflighted and the watcher has an opportunity * to premeptively cancel the move. * - * @param task The taskId to collect and move to the bottom. + * @param taskId The taskId to collect and move to the bottom. * @return Returns true if the move completed, false if not. */ - final boolean moveTaskToBackLocked(int task, ActivityRecord reason) { - Slog.i(TAG, "moveTaskToBack: " + task); + final boolean moveTaskToBackLocked(int taskId, ActivityRecord reason) { + Slog.i(TAG, "moveTaskToBack: " + taskId); // If we have a watcher, preflight the move before committing to it. First check // for *other* available tasks, but if none are available, then try again allowing the // current task to be selected. if (mStackSupervisor.isFrontStack(this) && mService.mController != null) { - ActivityRecord next = topRunningActivityLocked(null, task); + ActivityRecord next = topRunningActivityLocked(null, taskId); if (next == null) { next = topRunningActivityLocked(null, 0); } @@ -3024,9 +3024,9 @@ final class ActivityStack { } if (DEBUG_TRANSITION) Slog.v(TAG, - "Prepare to back transition: task=" + task); + "Prepare to back transition: task=" + taskId); - final TaskRecord tr = taskForIdLocked(task); + final TaskRecord tr = taskForIdLocked(taskId); if (tr == null) { return false; } @@ -3038,28 +3038,15 @@ final class ActivityStack { // We make sure here that some activity in the stack will launch home. ActivityRecord lastActivity = null; int numTasks = mTaskHistory.size(); - int taskNdx; - for (taskNdx = numTasks - 1; taskNdx >= 1; --taskNdx) { - final ArrayList activities = mTaskHistory.get(taskNdx).mActivities; - int activityNdx; - for (activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { - final ActivityRecord r = activities.get(activityNdx); - if (r.mLaunchHomeTaskNext) { - break; - } - if (taskNdx == 1 && activityNdx == 0) { - // Final activity before tr task. - lastActivity = r; - } - } - if (activityNdx >= 0) { - // Early exit, we found an activity that will launchHomeTaskNext. + for (int taskNdx = numTasks - 1; taskNdx >= 1; --taskNdx) { + final TaskRecord task = mTaskHistory.get(taskNdx); + if (task.mOnTopOfHome) { break; } - } - if (lastActivity != null) { - // No early exit, we did not find an activity that will launchHomeTaskNext, set one. - lastActivity.mLaunchHomeTaskNext = true; + if (taskNdx == 1) { + // Set the last task before tr to go to home. + task.mOnTopOfHome = true; + } } if (reason != null && @@ -3072,15 +3059,15 @@ final class ActivityStack { } else { mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_TO_BACK, false); } - mWindowManager.moveTaskToBottom(task); + mWindowManager.moveTaskToBottom(taskId); if (VALIDATE_TOKENS) { validateAppTokensLocked(); } - if (numTasks <= 1 || (mResumedActivity != null && mResumedActivity.task == tr && - mResumedActivity.mLaunchHomeTaskNext)) { - mResumedActivity.mLaunchHomeTaskNext = false; + final TaskRecord task = mResumedActivity != null ? mResumedActivity.task : null; + if (task == tr && task.mOnTopOfHome || numTasks <= 1) { + task.mOnTopOfHome = false; return mStackSupervisor.resumeHomeActivity(null); } @@ -3427,7 +3414,7 @@ final class ActivityStack { } final ActivityRecord top = topRunningActivityLocked(null); final boolean launchHomeTaskNext = - top != null && top.app == app && top.mLaunchHomeTaskNext; + top != null && top.app == app && top.task.mOnTopOfHome; // Remove this application's activities from active lists. boolean hasVisibleActivities = removeHistoryRecordsForAppLocked(app); @@ -3534,6 +3521,11 @@ final class ActivityStack { } boolean removeTask(TaskRecord task) { + final int taskNdx = mTaskHistory.indexOf(task); + final int topTaskNdx = mTaskHistory.size() - 1; + if (task.mOnTopOfHome && taskNdx < topTaskNdx) { + mTaskHistory.get(taskNdx + 1).mOnTopOfHome = true; + } mTaskHistory.remove(task); return mTaskHistory.isEmpty(); } diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java index 7756ff9ad6850..8ad29f3dfa103 100644 --- a/services/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/java/com/android/server/am/ActivityStackSupervisor.java @@ -282,7 +282,7 @@ public final class ActivityStackSupervisor { boolean resumeHomeActivity(ActivityRecord prev) { moveHomeStack(true); if (prev != null) { - prev.mLaunchHomeTaskNext = false; + prev.task.mOnTopOfHome = false; } mHomeStack.moveHomeTaskToTop(); ActivityRecord r = mHomeStack.topRunningActivityLocked(null); @@ -304,7 +304,7 @@ public final class ActivityStackSupervisor { r = stack.topRunningActivityLocked(null); } if (r != null && !r.isHomeActivity() && r.isRootActivity()) { - r.mLaunchHomeTaskNext = true; + r.task.mOnTopOfHome = true; } } } @@ -1429,7 +1429,7 @@ public final class ActivityStackSupervisor { (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) { // Caller wants to appear on home activity. - r.mLaunchHomeTaskNext = true; + intentActivity.task.mOnTopOfHome = true; } targetStack.moveTaskToFrontLocked(intentActivity.task, r, options); options = null; @@ -1543,7 +1543,7 @@ public final class ActivityStackSupervisor { // sure we have correctly resumed the top activity. if (doResume) { // Reset flag so it gets correctly reevaluated. - intentActivity.mLaunchHomeTaskNext = false; + intentActivity.task.mOnTopOfHome = false; setLaunchHomeTaskNextFlag(sourceRecord, intentActivity, targetStack); targetStack.resumeTopActivityLocked(null, options); } else { @@ -1640,7 +1640,7 @@ public final class ActivityStackSupervisor { == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) { // Caller wants to appear on home activity, so before starting // their own activity we will bring home to the front. - r.mLaunchHomeTaskNext = true; + r.task.mOnTopOfHome = true; } } } else if (sourceRecord != null) { diff --git a/services/java/com/android/server/am/TaskRecord.java b/services/java/com/android/server/am/TaskRecord.java index 479665c973d3e..f0bba4f99726c 100644 --- a/services/java/com/android/server/am/TaskRecord.java +++ b/services/java/com/android/server/am/TaskRecord.java @@ -60,6 +60,9 @@ final class TaskRecord extends ThumbnailHolder { /** Takes on same set of values as ActivityRecord.mActivityType */ private int mTaskType; + /** Launch the home activity when leaving this task. */ + boolean mOnTopOfHome = false; + TaskRecord(int _taskId, ActivityInfo info, Intent _intent) { taskId = _taskId; affinity = info.taskAffinity; @@ -411,11 +414,12 @@ final class TaskRecord extends ThumbnailHolder { } void dump(PrintWriter pw, String prefix) { - if (numActivities != 0 || rootWasReset || userId != 0) { + if (numActivities != 0 || rootWasReset || userId != 0 || numFullscreen != 0) { pw.print(prefix); pw.print("numActivities="); pw.print(numActivities); pw.print(" rootWasReset="); pw.print(rootWasReset); pw.print(" userId="); pw.print(userId); - pw.print(" numFullscreen="); pw.println(numFullscreen); + pw.print(" numFullscreen="); pw.print(numFullscreen); + pw.print(" mOnTopOfHome="); pw.println(mOnTopOfHome); } if (affinity != null) { pw.print(prefix); pw.print("affinity="); pw.println(affinity);