Modify task navigation to return to recent tasks.

Tasks launched from the recent task list will now return to the list
when they are finished. Also tasks that are launched from the
notification panel and services will now return to the list,
provided that the launcher is not front and center when they are
launched.

Fixes bug 14464114.

Change-Id: Ic0d3731fc7248d1eaa80e5ee399753d80e80c979
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 0ed5b10..c7ae6bc 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -31,6 +31,9 @@
 import static com.android.server.am.ActivityManagerService.DEBUG_USER_LEAVING;
 import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
 import static com.android.server.am.ActivityManagerService.TAG;
+import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
+import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
+import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
 
 import android.app.Activity;
 import android.app.ActivityManager;
@@ -344,18 +347,27 @@
         }
     }
 
-    void moveHomeToTop() {
+    void moveHomeStackTaskToTop(int homeStackTaskType) {
+        if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) {
+            mWindowManager.showRecentApps();
+            return;
+        }
         moveHomeStack(true);
-        mHomeStack.moveHomeTaskToTop();
+        mHomeStack.moveHomeStackTaskToTop(homeStackTaskType);
     }
 
-    boolean resumeHomeActivity(ActivityRecord prev) {
-        moveHomeToTop();
-        if (prev != null) {
-            prev.task.mOnTopOfHome = false;
+    boolean resumeHomeStackTask(int homeStackTaskType, ActivityRecord prev) {
+        if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) {
+            mWindowManager.showRecentApps();
+            return false;
         }
+        moveHomeStackTaskToTop(homeStackTaskType);
+        if (prev != null) {
+            prev.task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
+        }
+
         ActivityRecord r = mHomeStack.topRunningActivityLocked(null);
-        if (r != null && r.isHomeActivity()) {
+        if (r != null && (r.isHomeActivity() || r.isRecentsActivity())) {
             mService.setFocusedActivityLocked(r);
             return resumeTopActivitiesLocked(mHomeStack, prev, null);
         }
@@ -709,7 +721,7 @@
     }
 
     void startHomeActivity(Intent intent, ActivityInfo aInfo) {
-        moveHomeToTop();
+        moveHomeStackTaskToTop(HOME_ACTIVITY_TYPE);
         startActivityLocked(null, intent, null, aInfo, null, null, null, null, 0, 0, 0, null, 0,
                 null, false, null, null);
     }
@@ -1641,7 +1653,7 @@
                                     (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.
-                                intentActivity.task.mOnTopOfHome = true;
+                                intentActivity.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
                             }
                             options = null;
                         }
@@ -1825,6 +1837,11 @@
                         newTaskInfo != null ? newTaskInfo : r.info,
                         newTaskIntent != null ? newTaskIntent : intent,
                         voiceSession, voiceInteractor, true), null, true);
+                if (sourceRecord == null) {
+                    // Launched from a service or notification or task that is finishing.
+                    r.task.setTaskToReturnTo(isFrontStack(mHomeStack) ?
+                            mHomeStack.topTask().taskType : RECENTS_ACTIVITY_TYPE);
+                }
                 if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
                         r.task);
             } else {
@@ -1837,7 +1854,7 @@
                         == (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.task.mOnTopOfHome = r.task.stack.isOnHomeDisplay();
+                    r.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
                 }
             }
         } else if (sourceRecord != null) {
@@ -2188,7 +2205,7 @@
         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.mOnTopOfHome = true;
+            task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
         }
         task.stack.moveTaskToFrontLocked(task, null, options);
         if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
@@ -2299,7 +2316,7 @@
             }
             mWindowManager.addTask(taskId, stackId, false);
         }
-        resumeHomeActivity(null);
+        resumeHomeStackTask(HOME_ACTIVITY_TYPE, null);
     }
 
     void moveTaskToStack(int taskId, int stackId, boolean toTop) {
@@ -2556,7 +2573,7 @@
             }
         } else {
             // Stack was moved to another display while user was swapped out.
-            resumeHomeActivity(null);
+            resumeHomeStackTask(HOME_ACTIVITY_TYPE, null);
         }
         return homeInFront;
     }