Fixed some test failure and log warnings.

- Make DisplayContent.attachStack and moveStack use the same code
path for adding child stack so they both account for the presence
of pinnded stack.
- Don't call DC.attachStack on a stack that is already on the
display. Use DC.removeStack instead to just make sure it is at the
right z-order on the display.
- Use WindowContainer.getName() when for exception messages to have
a more concise print-out for the error.
- Only try to remove a task from a stack when positioning if the task
is contained in the stack.
- Throw an exception if we try to remove a task that isn't contained
in a stack.
- Skip checking of exiting or waiting for replacement when rebuilding
window list for app tokens that are exiting.
- Properly display and intent output from WC.dumpChildrenNames().
- Have DisplayContent WindowContainer type always return true for
fillsParent() and isVisible() as displays always fill their parent
and always visible for now.

Bug: 31624623
Test: Failing test passes.
Change-Id: I8a84770feb1fd278716755cdec2900fddb9940de
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 1a397ff..ba26e13 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -1100,12 +1100,16 @@
         }
     }
 
+    int rebuildWindowListUnchecked(DisplayContent dc, int addIndex) {
+        return super.rebuildWindowList(dc, addIndex);
+    }
+
     @Override
     int rebuildWindowList(DisplayContent dc, int addIndex) {
         if (mIsExiting && !waitingForReplacement()) {
             return addIndex;
         }
-        return super.rebuildWindowList(dc, addIndex);
+        return rebuildWindowListUnchecked(dc, addIndex);
     }
 
     @Override
@@ -1187,6 +1191,6 @@
             sb.append(" token="); sb.append(token); sb.append('}');
             stringName = sb.toString();
         }
-        return stringName;
+        return stringName + ((mIsExiting) ? " mIsExiting=" : "");
     }
 }
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 0ff30e2..a09c597 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -183,11 +183,11 @@
     /**
      * Returns true if the specified UID has access to this display.
      */
-    public boolean hasAccess(int uid) {
+    boolean hasAccess(int uid) {
         return mDisplay.hasAccess(uid);
     }
 
-    public boolean isPrivate() {
+    boolean isPrivate() {
         return (mDisplay.getFlags() & Display.FLAG_PRIVATE) != 0;
     }
 
@@ -237,11 +237,23 @@
         super.stepAppWindowsAnimation(currentTime, mDisplayId);
     }
 
+    @Override
+    boolean fillsParent() {
+        return true;
+    }
+
+    @Override
+    boolean isVisible() {
+        return true;
+    }
+
+    @Override
     void onAppTransitionDone() {
         super.onAppTransitionDone();
         rebuildAppWindowList();
     }
 
+    @Override
     int getOrientation() {
         if (mService.isStackVisibleLocked(DOCKED_STACK_ID)
                 || mService.isStackVisibleLocked(FREEFORM_WORKSPACE_STACK_ID)) {
@@ -322,8 +334,7 @@
             }
             mHomeStack = stack;
         }
-        addChild(stack, onTop ? mChildren.size() : 0);
-        layoutNeeded = true;
+        addChild(stack, onTop);
     }
 
     void moveStack(TaskStack stack, boolean toTop) {
@@ -337,7 +348,10 @@
             Slog.wtf(TAG_WM, "moving stack that was not added: " + stack, new Throwable());
         }
         removeChild(stack);
+        addChild(stack, toTop);
+    }
 
+    private void addChild(TaskStack stack, boolean toTop) {
         int addIndex = toTop ? mChildren.size() : 0;
 
         if (toTop
@@ -352,6 +366,7 @@
             }
         }
         addChild(stack, addIndex);
+        layoutNeeded = true;
     }
 
     /**
@@ -1063,7 +1078,7 @@
             AppTokenList exitingAppTokens = mChildren.get(stackNdx).mExitingAppTokens;
             int NT = exitingAppTokens.size();
             for (int j = 0; j < NT; j++) {
-                i = exitingAppTokens.get(j).rebuildWindowList(this, i);
+                i = exitingAppTokens.get(j).rebuildWindowListUnchecked(this, i);
             }
         }
 
@@ -1090,7 +1105,7 @@
                     ws.mWinAnimator.destroySurfaceLocked();
                 }
             }
-            Slog.w(TAG_WM, "Current app token list:");
+            Slog.w(TAG_WM, "Current window hierarchy:");
             dumpChildrenNames();
             Slog.w(TAG_WM, "Final window list:");
             dumpWindows();
@@ -1188,9 +1203,9 @@
     }
 
     private void dumpChildrenNames() {
-        StringWriter sw = new StringWriter();
-        PrintWriter pw = new FastPrintWriter(sw, false, 1024);
-        dumpChildrenNames(pw, "  ");
+        StringBuilder output = new StringBuilder();
+        dumpChildrenNames(output, " ");
+        Slog.v(TAG_WM, output.toString());
     }
 
     private void dumpWindows() {
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 8de267c..21b6ae5 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -232,8 +232,10 @@
 
             stack = dc.getStackById(stackId);
             if (stack != null) {
-                // It's already attached to the display...clear mDeferRemoval!
+                // It's already attached to the display...clear mDeferRemoval and move stack to
+                // appropriate z-order on display as needed.
                 stack.mDeferRemoval = false;
+                dc.moveStack(stack, onTop);
                 attachedToDisplay = true;
             } else {
                 stack = new TaskStack(mService, stackId);
@@ -245,14 +247,16 @@
                         .notifyDockedStackExistsChanged(true);
             }
         }
+
         if (!attachedToDisplay) {
             stack.attachDisplayContent(dc);
+            dc.attachStack(stack, onTop);
         }
-        dc.attachStack(stack, onTop);
+
         if (stack.getRawFullscreen()) {
             return null;
         }
-        Rect bounds = new Rect();
+        final Rect bounds = new Rect();
         stack.getRawBounds(bounds);
         return bounds;
     }
@@ -1425,4 +1429,9 @@
             }
         }
     }
+
+    @Override
+    String getName() {
+        return "ROOT";
+    }
 }
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index d6a1fae..e374185e 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -493,7 +493,9 @@
     void positionTask(Task task, int position, boolean showForAllUsers) {
         final boolean canShowTask =
                 showForAllUsers || mService.isCurrentProfileLocked(task.mUserId);
-        removeChild(task);
+        if (mChildren.contains(task)) {
+            super.removeChild(task);
+        }
         int stackSize = mChildren.size();
         int minPosition = 0;
         int maxPosition = stackSize;
@@ -589,10 +591,6 @@
     @Override
     void removeChild(Task task) {
         if (DEBUG_TASK_MOVEMENT) Slog.d(TAG_WM, "removeChild: task=" + task);
-        if (!mChildren.contains(task)) {
-            Slog.e(TAG_WM, "removeChild: task=" + this + " not found.");
-            return;
-        }
 
         super.removeChild(task);
 
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 4862265..af0fbd3 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -19,7 +19,6 @@
 import android.annotation.CallSuper;
 import android.view.animation.Animation;
 
-import java.io.PrintWriter;
 import java.util.Comparator;
 import java.util.LinkedList;
 
@@ -63,9 +62,9 @@
     @CallSuper
     protected void addChild(E child, Comparator<E> comparator) {
         if (child.mParent != null) {
-            throw new IllegalArgumentException("addChild: container=" + child
-                    + " is already a child of container=" + child.mParent
-                    + " can't add to container=" + this);
+            throw new IllegalArgumentException("addChild: container=" + child.getName()
+                    + " is already a child of container=" + child.mParent.getName()
+                    + " can't add to container=" + getName());
         }
         child.mParent = this;
 
@@ -89,9 +88,9 @@
     @CallSuper
     protected void addChild(E child, int index) {
         if (child.mParent != null) {
-            throw new IllegalArgumentException("addChild: container=" + child
-                    + " is already a child of container=" + child.mParent
-                    + " can't add to container=" + this);
+            throw new IllegalArgumentException("addChild: container=" + child.getName()
+                    + " is already a child of container=" + child.mParent.getName()
+                    + " can't add to container=" + getName());
         }
         child.mParent = this;
         mChildren.add(index, child);
@@ -107,8 +106,8 @@
         if (mChildren.remove(child)) {
             child.mParent = null;
         } else {
-            throw new IllegalArgumentException("removeChild: container=" + child
-                    + " is not a child of container=" + this);
+            throw new IllegalArgumentException("removeChild: container=" + child.getName()
+                    + " is not a child of container=" + getName());
         }
     }
 
@@ -469,12 +468,14 @@
      * Dumps the names of this container children in the input print writer indenting each
      * level with the input prefix.
      */
-    void dumpChildrenNames(PrintWriter pw, String prefix) {
-        final String childPrefix = prefix + prefix;
-        for (int i = mChildren.size() - 1; i >= 0; --i) {
+    void dumpChildrenNames(StringBuilder out, String prefix) {
+        final String childPrefix = prefix + " ";
+        out.append(getName() + "\n");
+        final int count = mChildren.size();
+        for (int i = 0; i < count; i++) {
             final WindowContainer wc = mChildren.get(i);
-            pw.println("#" + i + " " + getName());
-            wc.dumpChildrenNames(pw, childPrefix);
+            out.append(childPrefix + "#" + i + " ");
+            wc.dumpChildrenNames(out, childPrefix);
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index cd87fbd..ac907a9 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -3972,23 +3972,6 @@
         }
     }
 
-    public void addTask(int taskId, int stackId, boolean toTop) {
-        synchronized (mWindowMap) {
-            if (DEBUG_STACK) Slog.i(TAG_WM, "addTask: adding taskId=" + taskId
-                    + " to " + (toTop ? "top" : "bottom"));
-            Task task = mTaskIdToTask.get(taskId);
-            if (task == null) {
-                if (DEBUG_STACK) Slog.i(TAG_WM, "addTask: could not find taskId=" + taskId);
-                return;
-            }
-            TaskStack stack = mStackIdToStack.get(stackId);
-            stack.addTask(task, toTop);
-            final DisplayContent displayContent = stack.getDisplayContent();
-            displayContent.layoutNeeded = true;
-            mWindowPlacerLocked.performSurfacePlacement();
-        }
-    }
-
     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
         synchronized (mWindowMap) {
             if (DEBUG_STACK) Slog.i(TAG_WM, "moveTaskToStack: moving taskId=" + taskId
@@ -9203,6 +9186,13 @@
                     dumpWindowsLocked(pw, true, null);
                 }
                 return;
+            } else if ("containers".equals(cmd)) {
+                synchronized(mWindowMap) {
+                    StringBuilder output = new StringBuilder();
+                    mRoot.dumpChildrenNames(output, " ");
+                    pw.println(output.toString());
+                }
+                return;
             } else {
                 // Dumping a single name?
                 if (!dumpWindows(pw, cmd, args, opti, dumpAll)) {