Steady improvement to multi stack.

- Fix back button behavior with two stacks. Stopping activities were
held in that state indefinitely. This change causes IDLE_NOW_MSG to
be sent immediately for the last activity in a stack.

- Touch in non-focused stack was being ignored because of focus tests
in AbsListView.

- Change the focused stack when the activity focus changes. Renamed
mMainStack to mFocusedStack to reflect this.

- Resume all top stack activities when resuming.

- Assign intent task to ActivityRecord if it doesn't have a task.
Fixes bug 8433463.

Change-Id: I8d3c806234511697bc209ab99890730ffa514d20
diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java
index 8768688..8b946e4 100644
--- a/services/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/java/com/android/server/am/ActivityStackSupervisor.java
@@ -17,6 +17,8 @@
 package com.android.server.am;
 
 import static android.Manifest.permission.START_ANY_ACTIVITY;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static com.android.server.am.ActivityManagerService.localLOGV;
 import static com.android.server.am.ActivityManagerService.DEBUG_CONFIGURATION;
@@ -99,8 +101,8 @@
     private ActivityStack mHomeStack;
 
     /** The non-home stack currently receiving input or launching the next activity. If home is
-     * in front then mHomeStack overrides mMainStack. */
-    private ActivityStack mMainStack;
+     * in front then mHomeStack overrides mFocusedStack. */
+    private ActivityStack mFocusedStack;
 
     /** All the non-launcher stacks */
     private ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
@@ -150,7 +152,7 @@
             case STACK_STATE_HOME_IN_BACK:
             case STACK_STATE_HOME_TO_BACK:
             default:
-                return mMainStack;
+                return mFocusedStack;
         }
     }
 
@@ -162,7 +164,7 @@
             case STACK_STATE_HOME_TO_FRONT:
             case STACK_STATE_HOME_IN_BACK:
             default:
-                return mMainStack;
+                return mFocusedStack;
         }
     }
 
@@ -238,8 +240,8 @@
             mStacks.remove(stack);
             final int stackId = stack.mStackId;
             final int nextStackId = mService.mWindowManager.removeStack(stackId);
-            if (mMainStack.mStackId == stackId) {
-                mMainStack = nextStackId == HOME_STACK_ID ? null : getStack(nextStackId);
+            if (mFocusedStack.mStackId == stackId) {
+                mFocusedStack = nextStackId == HOME_STACK_ID ? null : getStack(nextStackId);
             }
         }
     }
@@ -329,10 +331,9 @@
     }
 
     boolean allPausedActivitiesComplete() {
-        final boolean homeInBack = !homeIsInFront();
         for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
             final ActivityStack stack = mStacks.get(stackNdx);
-            if (stack.isHomeStack() ^ homeInBack) {
+            if (isFrontStack(stack)) {
                 final ActivityRecord r = stack.mLastPausedActivity;
                 if (r != null && r.state != ActivityState.PAUSED
                         && r.state != ActivityState.STOPPED
@@ -353,6 +354,35 @@
         return true;
     }
 
+    ActivityRecord topRunningActivityLocked() {
+        ActivityRecord r = null;
+        if (mFocusedStack != null) {
+            r = mFocusedStack.topRunningActivityLocked(null);
+            if (r != null) {
+                return r;
+            }
+        }
+        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+            final ActivityStack stack = mStacks.get(stackNdx);
+            if (stack != mFocusedStack && isFrontStack(stack)) {
+                r = stack.topRunningActivityLocked(null);
+                if (r != null) {
+                    return r;
+                }
+            }
+        }
+        return null;
+    }
+
+    void resumeTopActivitiesLocked() {
+        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+            final ActivityStack stack = mStacks.get(stackNdx);
+            if (isFrontStack(stack)) {
+                stack.resumeTopActivityLocked(null);
+            }
+        }
+    }
+
     ActivityRecord getTasksLocked(int maxNum, IThumbnailReceiver receiver,
             PendingThumbnailsRecord pending, List<RunningTaskInfo> list) {
         ActivityRecord r = null;
@@ -1043,13 +1073,29 @@
                 // Time to create the first app stack.
                 int stackId = mService.createStack(-1, HOME_STACK_ID,
                         StackBox.TASK_STACK_GOES_OVER, 1.0f);
-                mMainStack = getStack(stackId);
+                mFocusedStack = getStack(stackId);
             }
-            return mMainStack;
+            return mFocusedStack;
         }
         return mHomeStack;
     }
 
+    void setFocusedStack(ActivityRecord r) {
+        if (r == null) {
+            return;
+        }
+        if (r.isHomeActivity) {
+            if (mStackState != STACK_STATE_HOME_IN_FRONT) {
+                mStackState = STACK_STATE_HOME_TO_FRONT;
+            }
+        } else {
+            mFocusedStack = r.task.stack;
+            if (mStackState != STACK_STATE_HOME_IN_BACK) {
+                mStackState = STACK_STATE_HOME_TO_BACK;
+            }
+        }
+    }
+
     final int startActivityUncheckedLocked(ActivityRecord r,
             ActivityRecord sourceRecord, int startFlags, boolean doResume,
             Bundle options) {
@@ -1091,8 +1137,8 @@
             // This activity is not being started from another...  in this
             // case we -always- start a new task.
             if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
-                Slog.w(TAG, "startActivity called from non-Activity context; forcing Intent.FLAG_ACTIVITY_NEW_TASK for: "
-                      + intent);
+                Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
+                        "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
                 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
             }
         } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
@@ -1150,6 +1196,9 @@
                         ? findTaskLocked(intent, r.info)
                         : findActivityLocked(intent, r.info);
                 if (intentActivity != null) {
+                    if (r.task == null) {
+                        r.task = intentActivity.task;
+                    }
                     targetStack = intentActivity.task.stack;
                     moveHomeStack(targetStack.isHomeStack());
                     if (intentActivity.task.intent == null) {
@@ -1174,8 +1223,8 @@
                             // user's face, right now.
                             movedHome = true;
                             if ((launchFlags &
-                                    (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
-                                    == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
+                                    (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, so before starting
                                 // their own activity we will bring home to the front.
                                 r.mLaunchHomeTaskNext = true;
@@ -1200,6 +1249,9 @@
                         } else {
                             ActivityOptions.abort(options);
                         }
+                        if (r.task == null)  Slog.v(TAG,
+                                "startActivityUncheckedLocked: task left null",
+                                new RuntimeException("here").fillInStackTrace());
                         return ActivityManager.START_RETURN_INTENT_TO_CALLER;
                     }
                     if ((launchFlags &
@@ -1293,6 +1345,9 @@
                         } else {
                             ActivityOptions.abort(options);
                         }
+                        if (r.task == null)  Slog.v(TAG,
+                            "startActivityUncheckedLocked: task left null",
+                            new RuntimeException("here").fillInStackTrace());
                         return ActivityManager.START_TASK_TO_FRONT;
                     }
                 }
@@ -1330,9 +1385,15 @@
                                 // We don't need to start a new activity, and
                                 // the client said not to do anything if that
                                 // is the case, so this is it!
+                                if (r.task == null)  Slog.v(TAG,
+                                    "startActivityUncheckedLocked: task left null",
+                                    new RuntimeException("here").fillInStackTrace());
                                 return ActivityManager.START_RETURN_INTENT_TO_CALLER;
                             }
                             top.deliverNewIntentLocked(callingUid, r.intent);
+                            if (r.task == null)  Slog.v(TAG,
+                                "startActivityUncheckedLocked: task left null",
+                                new RuntimeException("here").fillInStackTrace());
                             return ActivityManager.START_DELIVERED_TO_TOP;
                         }
                     }
@@ -1345,6 +1406,9 @@
                         r.requestCode, Activity.RESULT_CANCELED, null);
             }
             ActivityOptions.abort(options);
+            if (r.task == null)  Slog.v(TAG,
+                "startActivityUncheckedLocked: task left null",
+                new RuntimeException("here").fillInStackTrace());
             return ActivityManager.START_CLASS_NOT_FOUND;
         }
 
@@ -1394,6 +1458,9 @@
                         targetStack.resumeTopActivityLocked(null);
                     }
                     ActivityOptions.abort(options);
+                    if (r.task == null)  Slog.v(TAG,
+                        "startActivityUncheckedLocked: task left null",
+                        new RuntimeException("here").fillInStackTrace());
                     return ActivityManager.START_DELIVERED_TO_TOP;
                 }
             } else if (!addingToTask &&
@@ -1413,6 +1480,9 @@
                         setLaunchHomeTaskNextFlag(sourceRecord, null, targetStack);
                         targetStack.resumeTopActivityLocked(null);
                     }
+                    if (r.task == null)  Slog.v(TAG,
+                        "startActivityUncheckedLocked: task left null",
+                        new RuntimeException("here").fillInStackTrace());
                     return ActivityManager.START_DELIVERED_TO_TOP;
                 }
             }