Implement separate stacks.

One for home activity(s), one for other activities. Coordination
between the stacks is handled by the ActivityStackSupervisor.

Change-Id: I11395edea501d2f84a18a6a8bced1ce3d0797dad
diff --git a/services/java/com/android/server/wm/DisplayContent.java b/services/java/com/android/server/wm/DisplayContent.java
index 75df1ec..5b2cf50 100644
--- a/services/java/com/android/server/wm/DisplayContent.java
+++ b/services/java/com/android/server/wm/DisplayContent.java
@@ -17,8 +17,11 @@
 package com.android.server.wm;
 
 import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
+import static com.android.server.wm.WindowManagerService.DEBUG_STACK;
+import static com.android.server.wm.WindowManagerService.TAG;
 
 import android.graphics.Rect;
+import android.util.Slog;
 import android.view.Display;
 import android.view.DisplayInfo;
 
@@ -36,7 +39,6 @@
  * WindowManagerService.mWindowMap.
  */
 class DisplayContent {
-//    private final static String TAG = "DisplayContent";
 
     /** Unique identifier of this stack. */
     private final int mDisplayId;
@@ -86,7 +88,7 @@
     private ArrayList<StackBox> mStackBoxes = new ArrayList<StackBox>();
 
     /** True when the home StackBox is at the top of mStackBoxes, false otherwise */
-    private boolean mHomeOnTop = true;
+    private TaskStack mHomeStack = null;
 
     /**
      * Sorted most recent at top, oldest at [0].
@@ -120,7 +122,7 @@
     }
 
     boolean homeOnTop() {
-        return mHomeOnTop;
+        return mStackBoxes.get(0).mStack != mHomeStack;
     }
 
     /**
@@ -138,7 +140,7 @@
     }
 
     TaskStack getHomeStack() {
-        return mStackBoxes.get(mHomeOnTop ? mStackBoxes.size() - 1 : 0).mStack;
+        return mHomeStack;
     }
 
     public void updateDisplayInfo() {
@@ -158,12 +160,19 @@
     /** Refer to {@link WindowManagerService#createStack(int, int, int, float)} */
     TaskStack createStack(int stackId, int relativeStackId, int position, float weight) {
         TaskStack newStack = null;
+        if (DEBUG_STACK) Slog.d(TAG, "createStack: stackId=" + stackId + " relativeStackId="
+                + relativeStackId + " position=" + position + " weight=" + weight);
         if (mStackBoxes.isEmpty()) {
+            if (stackId != HOME_STACK_ID) {
+                throw new IllegalArgumentException("createStack: First stackId not "
+                        + HOME_STACK_ID);
+            }
             StackBox newBox = new StackBox(this, new Rect(0, 0, mDisplayInfo.logicalWidth,
                     mDisplayInfo.logicalHeight));
             mStackBoxes.add(newBox);
             newStack = new TaskStack(stackId, newBox);
             newBox.mStack = newStack;
+            mHomeStack = newStack;
         } else {
             int stackBoxNdx;
             for (stackBoxNdx = mStackBoxes.size() - 1; stackBoxNdx >= 0; --stackBoxNdx) {
@@ -172,10 +181,12 @@
                         || position == StackBox.TASK_STACK_GOES_UNDER) {
                     // Position indicates a new box is added at top level only.
                     if (box.contains(relativeStackId)) {
-                        final int offset = position == StackBox.TASK_STACK_GOES_OVER ? 1 : 0;
                         StackBox newBox = new StackBox(this, box.mBounds);
                         newStack = new TaskStack(stackId, newBox);
                         newBox.mStack = newStack;
+                        final int offset = position == StackBox.TASK_STACK_GOES_OVER ? 1 : 0;
+                        if (DEBUG_STACK) Slog.d(TAG, "createStack: inserting stack at " +
+                                (stackBoxNdx + offset));
                         mStackBoxes.add(stackBoxNdx + offset, newBox);
                         break;
                     }
@@ -208,9 +219,11 @@
     }
 
     void removeStackBox(StackBox box) {
+        if (DEBUG_STACK) Slog.d(TAG, "removeStackBox: box=" + box);
         final TaskStack stack = box.mStack;
         if (stack != null && stack.mStackId == HOME_STACK_ID) {
             // Never delete the home stack, even if it is empty.
+            if (DEBUG_STACK) Slog.d(TAG, "removeStackBox: Not deleting home stack.");
             return;
         }
         mStackBoxes.remove(box);
@@ -223,14 +236,13 @@
      * @return true if a change was made, false otherwise.
      */
     boolean moveHomeStackBox(boolean toTop) {
+        if (DEBUG_STACK) Slog.d(TAG, "moveHomeStackBox: toTop=" + toTop);
         switch (mStackBoxes.size()) {
             case 0: throw new RuntimeException("moveHomeStackBox: No home StackBox!");
             case 1: return false; // Only the home StackBox exists.
-            case 2: 
-                if (mHomeOnTop != toTop) {
-                    final StackBox home = mStackBoxes.remove(toTop ? 0 : 1);
-                    mStackBoxes.add(toTop ? 1 : 0, home);
-                    mHomeOnTop = toTop;
+            case 2:
+                if (homeOnTop() ^ toTop) {
+                    mStackBoxes.add(mStackBoxes.remove(0));
                     return true;
                 }
                 return false;
@@ -262,47 +274,47 @@
             pw.print("-"); pw.print(mDisplayInfo.largestNominalAppWidth);
             pw.print("x"); pw.println(mDisplayInfo.largestNominalAppHeight);
             pw.print(subPrefix); pw.print("layoutNeeded="); pw.println(layoutNeeded);
-            for (int boxNdx = 0; boxNdx < mStackBoxes.size(); ++boxNdx) {
-                pw.print(prefix); pw.print("StackBox #"); pw.println(boxNdx);
-                mStackBoxes.get(boxNdx).dump(prefix + "  ", pw);
-            }
-            int ndx = numTokens();
-            if (ndx > 0) {
-                pw.println();
-                pw.println("  Application tokens in Z order:");
-                getTasks();
-                for (int taskNdx = mTmpTasks.size() - 1; taskNdx >= 0; --taskNdx) {
-                    AppTokenList tokens = mTmpTasks.get(taskNdx).mAppTokens;
-                    for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
-                        final AppWindowToken wtoken = tokens.get(tokenNdx);
-                        pw.print("  App #"); pw.print(ndx--);
-                                pw.print(' '); pw.print(wtoken); pw.println(":");
-                        wtoken.dump(pw, "    ");
-                    }
+        for (int boxNdx = 0; boxNdx < mStackBoxes.size(); ++boxNdx) {
+            pw.print(prefix); pw.print("StackBox #"); pw.println(boxNdx);
+            mStackBoxes.get(boxNdx).dump(prefix + "  ", pw);
+        }
+        int ndx = numTokens();
+        if (ndx > 0) {
+            pw.println();
+            pw.println("  Application tokens in Z order:");
+            getTasks();
+            for (int taskNdx = mTmpTasks.size() - 1; taskNdx >= 0; --taskNdx) {
+                AppTokenList tokens = mTmpTasks.get(taskNdx).mAppTokens;
+                for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
+                    final AppWindowToken wtoken = tokens.get(tokenNdx);
+                    pw.print("  App #"); pw.print(ndx--);
+                            pw.print(' '); pw.print(wtoken); pw.println(":");
+                    wtoken.dump(pw, "    ");
                 }
             }
-            if (mExitingTokens.size() > 0) {
-                pw.println();
-                pw.println("  Exiting tokens:");
-                for (int i=mExitingTokens.size()-1; i>=0; i--) {
-                    WindowToken token = mExitingTokens.get(i);
-                    pw.print("  Exiting #"); pw.print(i);
-                    pw.print(' '); pw.print(token);
-                    pw.println(':');
-                    token.dump(pw, "    ");
-                }
+        }
+        if (mExitingTokens.size() > 0) {
+            pw.println();
+            pw.println("  Exiting tokens:");
+            for (int i=mExitingTokens.size()-1; i>=0; i--) {
+                WindowToken token = mExitingTokens.get(i);
+                pw.print("  Exiting #"); pw.print(i);
+                pw.print(' '); pw.print(token);
+                pw.println(':');
+                token.dump(pw, "    ");
             }
-            if (mExitingAppTokens.size() > 0) {
-                pw.println();
-                pw.println("  Exiting application tokens:");
-                for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
-                    WindowToken token = mExitingAppTokens.get(i);
-                    pw.print("  Exiting App #"); pw.print(i);
-                      pw.print(' '); pw.print(token);
-                      pw.println(':');
-                      token.dump(pw, "    ");
-                }
+        }
+        if (mExitingAppTokens.size() > 0) {
+            pw.println();
+            pw.println("  Exiting application tokens:");
+            for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
+                WindowToken token = mExitingAppTokens.get(i);
+                pw.print("  Exiting App #"); pw.print(i);
+                  pw.print(' '); pw.print(token);
+                  pw.println(':');
+                  token.dump(pw, "    ");
             }
+        }
         pw.println();
     }
 }