Switched WindowToken/AppWindowToken to use WindowContainer

Bug: 30060889
Change-Id: Ia82aedfd9ea86410acdcd3a55a7a7fc456be2fc3
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 66fa976..518b9b5 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -18,6 +18,7 @@
 
 import static android.app.ActivityManager.StackId;
 import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
@@ -149,29 +150,14 @@
     ArrayDeque<Rect> mFrozenBounds = new ArrayDeque<>();
     ArrayDeque<Configuration> mFrozenMergedConfig = new ArrayDeque<>();
 
-    AppWindowToken(WindowManagerService service, IApplicationToken _token, boolean _voiceInteraction) {
-        super(service, _token.asBinder(), WindowManager.LayoutParams.TYPE_APPLICATION, true);
-        appToken = _token;
+    AppWindowToken(WindowManagerService service, IApplicationToken token, boolean _voiceInteraction) {
+        super(service, token != null ? token.asBinder() : null, TYPE_APPLICATION, true);
+        appToken = token;
         voiceInteraction = _voiceInteraction;
         mInputApplicationHandle = new InputApplicationHandle(this);
         mAppAnimator = new AppWindowAnimator(this, service);
     }
 
-    void sendAppVisibilityToClients() {
-        final int count = windows.size();
-        for (int i = 0; i < count; i++) {
-            final WindowState win = windows.get(i);
-            win.sendAppVisibilityToClients(clientHidden);
-        }
-    }
-
-    void setVisibleBeforeClientHidden() {
-        for (int i = windows.size() - 1; i >= 0; i--) {
-            final WindowState w = windows.get(i);
-            w.setVisibleBeforeClientHidden();
-        }
-    }
-
     void onFirstWindowDrawn(WindowState win, WindowStateAnimator winAnimator) {
         firstWindowDrawn = true;
 
@@ -197,12 +183,12 @@
         }
 
         if (DEBUG_VISIBILITY) Slog.v(TAG, "Update reported visibility: " + this);
-        final int count = windows.size();
+        final int count = mChildren.size();
 
         mReportedVisibilityResults.reset();
 
         for (int i = 0; i < count; i++) {
-            final WindowState win = windows.get(i);
+            final WindowState win = (WindowState) mChildren.get(i);
             win.updateReportedVisibility(mReportedVisibilityResults);
         }
 
@@ -280,9 +266,9 @@
                 changed = true;
             }
 
-            final int windowsCount = windows.size();
+            final int windowsCount = mChildren.size();
             for (int i = 0; i < windowsCount; i++) {
-                final WindowState win = windows.get(i);
+                final WindowState win = (WindowState) mChildren.get(i);
                 changed |= win.onAppVisibilityChanged(visible, runningAppAnimation);
             }
 
@@ -317,8 +303,8 @@
             delayed = true;
         }
 
-        for (int i = windows.size() - 1; i >= 0 && !delayed; i--) {
-            if (windows.get(i).isWindowAnimationSet()) {
+        for (int i = mChildren.size() - 1; i >= 0 && !delayed; i--) {
+            if (((WindowState) mChildren.get(i)).isWindowAnimationSet()) {
                 delayed = true;
             }
         }
@@ -345,10 +331,10 @@
 
     WindowState findMainWindow() {
         WindowState candidate = null;
-        int j = windows.size();
+        int j = mChildren.size();
         while (j > 0) {
             j--;
-            final WindowState win = windows.get(j);
+            final WindowState win = (WindowState) mChildren.get(j);
             final int type = win.mAttrs.type;
             // No need to loop through child window as base application and starting types can't be
             // child windows.
@@ -370,27 +356,6 @@
         return StackId.canReceiveKeys(mTask.mStack.mStackId) || mAlwaysFocusable;
     }
 
-    boolean isVisible() {
-        final int count = windows.size();
-        for (int i = 0; i < count; i++) {
-            final WindowState win = windows.get(i);
-            if (win.isVisible()) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    boolean canBeVisibleForCurrentUser() {
-        for (int j = windows.size() - 1; j >= 0; j--) {
-            final WindowState w = windows.get(j);
-            if (!w.isHiddenFromUserLocked()) {
-                return true;
-            }
-        }
-        return false;
-    }
-
     void removeAppFromTaskLocked() {
         mIsExiting = false;
         removeAllWindows();
@@ -408,8 +373,8 @@
 
     void clearAnimatingFlags() {
         boolean wallpaperMightChange = false;
-        for (int i = windows.size() - 1; i >= 0; i--) {
-            final WindowState win = windows.get(i);
+        for (int i = mChildren.size() - 1; i >= 0; i--) {
+            final WindowState win = (WindowState) mChildren.get(i);
             wallpaperMightChange |= win.clearAnimatingFlags();
         }
         if (wallpaperMightChange) {
@@ -432,8 +397,8 @@
      */
     private void destroySurfaces(boolean cleanupOnResume) {
         final DisplayContentList displayList = new DisplayContentList();
-        for (int i = windows.size() - 1; i >= 0; i--) {
-            final WindowState win = windows.get(i);
+        for (int i = mChildren.size() - 1; i >= 0; i--) {
+            final WindowState win = (WindowState) mChildren.get(i);
             final boolean destroyed = win.destroySurface(cleanupOnResume, mAppStopped);
 
             if (destroyed) {
@@ -491,9 +456,9 @@
         return allDrawn;
     }
 
-    boolean canRestoreSurfaces() {
-        for (int i = windows.size() -1; i >= 0; i--) {
-            final WindowState w = windows.get(i);
+    private boolean canRestoreSurfaces() {
+        for (int i = mChildren.size() -1; i >= 0; i--) {
+            final WindowState w = (WindowState) mChildren.get(i);
             if (w.canRestoreSurface()) {
                 return true;
             }
@@ -501,9 +466,9 @@
         return false;
     }
 
-    void clearWasVisibleBeforeClientHidden() {
-        for (int i = windows.size() - 1; i >= 0; i--) {
-            final WindowState w = windows.get(i);
+    private void clearWasVisibleBeforeClientHidden() {
+        for (int i = mChildren.size() - 1; i >= 0; i--) {
+            final WindowState w = (WindowState) mChildren.get(i);
             w.clearWasVisibleBeforeClientHidden();
         }
     }
@@ -513,8 +478,8 @@
      * animating with saved surface.
      */
     boolean isAnimatingInvisibleWithSavedSurface() {
-        for (int i = windows.size() - 1; i >= 0; i--) {
-            final WindowState w = windows.get(i);
+        for (int i = mChildren.size() - 1; i >= 0; i--) {
+            final WindowState w = (WindowState) mChildren.get(i);
             if (w.isAnimatingInvisibleWithSavedSurface()) {
                 return true;
             }
@@ -527,16 +492,16 @@
      * with a saved surface, and mark them destroying.
      */
     void stopUsingSavedSurfaceLocked() {
-        for (int i = windows.size() - 1; i >= 0; i--) {
-            final WindowState w = windows.get(i);
+        for (int i = mChildren.size() - 1; i >= 0; i--) {
+            final WindowState w = (WindowState) mChildren.get(i);
             w.stopUsingSavedSurface();
         }
         destroySurfaces();
     }
 
     void markSavedSurfaceExiting() {
-        for (int i = windows.size() - 1; i >= 0; i--) {
-            final WindowState w = windows.get(i);
+        for (int i = mChildren.size() - 1; i >= 0; i--) {
+            final WindowState w = (WindowState) mChildren.get(i);
             w.markSavedSurfaceExiting();
         }
     }
@@ -550,8 +515,8 @@
         // Check if all interesting windows are drawn and we can mark allDrawn=true.
         int interestingNotDrawn = -1;
 
-        for (int i = windows.size() - 1; i >= 0; i--) {
-            final WindowState w = windows.get(i);
+        for (int i = mChildren.size() - 1; i >= 0; i--) {
+            final WindowState w = (WindowState) mChildren.get(i);
             interestingNotDrawn = w.restoreSavedSurfaceForInterestingWindow();
         }
 
@@ -569,8 +534,8 @@
     }
 
     void destroySavedSurfaces() {
-        for (int i = windows.size() - 1; i >= 0; i--) {
-            final WindowState win = windows.get(i);
+        for (int i = mChildren.size() - 1; i >= 0; i--) {
+            final WindowState win = (WindowState) mChildren.get(i);
             win.destroySavedSurface();
         }
     }
@@ -589,12 +554,12 @@
         if (startingWindow == win) {
             if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Notify removed startingWindow " + win);
             mService.scheduleRemoveStartingWindowLocked(this);
-        } else if (windows.size() == 0 && startingData != null) {
+        } else if (mChildren.size() == 0 && startingData != null) {
             // If this is the last window and we had requested a starting transition window,
             // well there is no point now.
             if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Nulling last startingWindow");
             startingData = null;
-        } else if (windows.size() == 1 && startingView != null) {
+        } else if (mChildren.size() == 1 && startingView != null) {
             // If this is the last window except for a starting transition window,
             // we need to get rid of the starting transition.
             mService.scheduleRemoveStartingWindowLocked(this);
@@ -602,14 +567,8 @@
     }
 
     void removeDeadWindows() {
-        for (int winNdx = windows.size() - 1; winNdx >= 0;
-            // WindowState#removeIfPossible() at bottom of loop may remove multiple entries from
-            // windows if the window to be removed has child windows. It also may
-            // not remove any windows from windows at all if win is exiting and
-            // currently animating away. This ensures that winNdx is monotonically decreasing
-            // and never beyond windows bounds.
-            winNdx = Math.min(winNdx - 1, windows.size() - 1)) {
-            WindowState win = windows.get(winNdx);
+        for (int winNdx = mChildren.size() - 1; winNdx >= 0; --winNdx) {
+            WindowState win = (WindowState) mChildren.get(winNdx);
             if (win.mAppDied) {
                 if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.w(TAG,
                         "removeDeadWindows: " + win);
@@ -622,10 +581,10 @@
     }
 
     boolean hasWindowsAlive() {
-        for (int i = windows.size() - 1; i >= 0; i--) {
+        for (int i = mChildren.size() - 1; i >= 0; i--) {
             // No need to loop through child windows as the answer should be the same as that of the
             // parent window.
-            if (!windows.get(i).mAppDied) {
+            if (!((WindowState) mChildren.get(i)).mAppDied) {
                 return true;
             }
         }
@@ -636,8 +595,8 @@
         if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
                 "Marking app token " + this + " with replacing windows.");
 
-        for (int i = windows.size() - 1; i >= 0; i--) {
-            final WindowState w = windows.get(i);
+        for (int i = mChildren.size() - 1; i >= 0; i--) {
+            final WindowState w = (WindowState) mChildren.get(i);
             w.setWillReplaceWindow(animate);
         }
         if (animate) {
@@ -653,8 +612,8 @@
     void setWillReplaceChildWindows() {
         if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "Marking app token " + this
                 + " with replacing child windows.");
-        for (int i = windows.size() - 1; i >= 0; i--) {
-            final WindowState w = windows.get(i);
+        for (int i = mChildren.size() - 1; i >= 0; i--) {
+            final WindowState w = (WindowState) mChildren.get(i);
             w.setWillReplaceChildWindows();
         }
     }
@@ -663,15 +622,15 @@
         if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
                 "Resetting app token " + this + " of replacing window marks.");
 
-        for (int i = windows.size() - 1; i >= 0; i--) {
-            final WindowState w = windows.get(i);
+        for (int i = mChildren.size() - 1; i >= 0; i--) {
+            final WindowState w = (WindowState) mChildren.get(i);
             w.clearWillReplaceWindow();
         }
     }
 
     void requestUpdateWallpaperIfNeeded() {
-        for (int i = windows.size() - 1; i >= 0; i--) {
-            final WindowState w = windows.get(i);
+        for (int i = mChildren.size() - 1; i >= 0; i--) {
+            final WindowState w = (WindowState) mChildren.get(i);
             w.requestUpdateWallpaperIfNeeded();
         }
     }
@@ -711,8 +670,8 @@
         super.addWindow(w);
 
         boolean gotReplacementWindow = false;
-        for (int i = windows.size() - 1; i >= 0; i--) {
-            final WindowState candidate = windows.get(i);
+        for (int i = mChildren.size() - 1; i >= 0; i--) {
+            final WindowState candidate = (WindowState) mChildren.get(i);
             gotReplacementWindow |= candidate.setReplacementWindowIfNeeded(w);
         }
 
@@ -723,8 +682,8 @@
     }
 
     boolean waitingForReplacement() {
-        for (int i = windows.size() - 1; i >= 0; i--) {
-            final WindowState candidate = windows.get(i);
+        for (int i = mChildren.size() - 1; i >= 0; i--) {
+            final WindowState candidate = (WindowState) mChildren.get(i);
             if (candidate.waitingForReplacement()) {
                 return true;
             }
@@ -733,8 +692,8 @@
     }
 
     void onWindowReplacementTimeout() {
-        for (int i = windows.size() - 1; i >= 0; --i) {
-            windows.get(i).onWindowReplacementTimeout();
+        for (int i = mChildren.size() - 1; i >= 0; --i) {
+            ((WindowState) mChildren.get(i)).onWindowReplacementTimeout();
         }
     }
 
@@ -774,8 +733,8 @@
         if (!mFrozenMergedConfig.isEmpty()) {
             mFrozenMergedConfig.remove();
         }
-        for (int i = windows.size() - 1; i >= 0; i--) {
-            final WindowState win = windows.get(i);
+        for (int i = mChildren.size() - 1; i >= 0; i--) {
+            final WindowState win = (WindowState) mChildren.get(i);
             win.onUnfreezeBounds();
         }
         mService.mWindowPlacerLocked.performSurfacePlacement();
@@ -824,80 +783,23 @@
     }
 
     void resetJustMovedInStack() {
-        for (int i = windows.size() - 1; i >= 0; i--) {
-            windows.get(i).resetJustMovedInStack();
-        }
-    }
-
-    void setWaitingForDrawnIfResizingChanged() {
-        for (int i = windows.size() - 1; i >= 0; --i) {
-            final WindowState win = windows.get(i);
-            win.setWaitingForDrawnIfResizingChanged();
-        }
-    }
-
-    void resizeWindows() {
-        for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
-            final WindowState win = windows.get(winNdx);
-            win.addToResizingList();
-        }
-    }
-
-    void setMovedByResize() {
-        for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
-            final WindowState win = windows.get(winNdx);
-            win.setMovedByResize();
+        for (int i = mChildren.size() - 1; i >= 0; i--) {
+            ((WindowState) mChildren.get(i)).resetJustMovedInStack();
         }
     }
 
     void notifyMovedInStack() {
-        for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
-            final WindowState win = windows.get(winNdx);
+        for (int winNdx = mChildren.size() - 1; winNdx >= 0; --winNdx) {
+            final WindowState win = (WindowState) mChildren.get(winNdx);
             win.notifyMovedInStack();
         }
     }
 
-    void resetDragResizingChangeReported() {
-        for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
-            final WindowState win = windows.get(winNdx);
-            win.resetDragResizingChangeReported();
-        }
-    }
-
-    void detachDisplay() {
-        boolean doAnotherLayoutPass = false;
-        for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
-            // We are in the middle of changing the state of displays/stacks/tasks. We need
-            // to finish that, before we let layout interfere with it.
-            // Also removes child windows.
-            windows.get(winNdx).removeIfPossible();
-            doAnotherLayoutPass = true;
-        }
-        if (doAnotherLayoutPass) {
-            mService.mWindowPlacerLocked.requestTraversal();
-        }
-    }
-
-    void forceWindowsScaleableInTransaction(boolean force) {
-        for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
-            windows.get(winNdx).forceWindowsScaleableInTransaction(force);
-        }
-    }
-
-    boolean isAnimating() {
-        for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
-            if (windows.get(winNdx).isAnimating()) {
-                return true;
-            }
-        }
-        return false;
-    }
-
     void setAppLayoutChanges(int changes, String reason, int displayId) {
         final WindowAnimator windowAnimator = mAppAnimator.mAnimator;
-        for (int i = windows.size() - 1; i >= 0; i--) {
+        for (int i = mChildren.size() - 1; i >= 0; i--) {
             // Child windows will be on the same display as their parents.
-            if (displayId == windows.get(i).getDisplayId()) {
+            if (displayId == ((WindowState) mChildren.get(i)).getDisplayId()) {
                 windowAnimator.setPendingLayoutChanges(displayId, changes);
                 if (DEBUG_LAYOUT_REPEATS) {
                     mService.mWindowPlacerLocked.debugLayoutRepeats(
@@ -909,8 +811,8 @@
     }
 
     void removeReplacedWindowIfNeeded(WindowState replacement) {
-        for (int i = windows.size() - 1; i >= 0; i--) {
-            final WindowState win = windows.get(i);
+        for (int i = mChildren.size() - 1; i >= 0; i--) {
+            final WindowState win = (WindowState) mChildren.get(i);
             if (win.removeReplacedWindowIfNeeded(replacement)) {
                 return;
             }
@@ -932,9 +834,9 @@
                     mService.mH.sendEmptyMessageDelayed(H.APP_FREEZE_TIMEOUT, 2000);
                 }
             }
-            final int count = windows.size();
+            final int count = mChildren.size();
             for (int i = 0; i < count; i++) {
-                final WindowState w = windows.get(i);
+                final WindowState w = (WindowState) mChildren.get(i);
                 w.onStartFreezingScreen();
             }
         }
@@ -945,10 +847,10 @@
             return;
         }
         if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Clear freezing of " + this + " force=" + force);
-        final int count = windows.size();
+        final int count = mChildren.size();
         boolean unfrozeWindows = false;
         for (int i = 0; i < count; i++) {
-            final WindowState w = windows.get(i);
+            final WindowState w = (WindowState) mChildren.get(i);
             unfrozeWindows |= w.onStopFreezingScreen();
         }
         if (force || unfrozeWindows) {
@@ -1065,16 +967,16 @@
     }
 
     boolean isLastWindow(WindowState win) {
-        return windows.size() == 1 && windows.get(0) == win;
+        return mChildren.size() == 1 && mChildren.get(0) == win;
     }
 
     void setAllAppWinAnimators() {
         final ArrayList<WindowStateAnimator> allAppWinAnimators = mAppAnimator.mAllAppWinAnimators;
         allAppWinAnimators.clear();
 
-        final int windowsCount = windows.size();
+        final int windowsCount = mChildren.size();
         for (int j = 0; j < windowsCount; j++) {
-            windows.get(j).addWinAnimatorToList(allAppWinAnimators);
+            ((WindowState) mChildren.get(j)).addWinAnimatorToList(allAppWinAnimators);
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 26be088..990405a 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -624,7 +624,7 @@
      */
     TaskStack getDockedStackLocked() {
         final TaskStack stack = mService.mStackIdToStack.get(DOCKED_STACK_ID);
-        return (stack != null && stack.isVisibleLocked()) ? stack : null;
+        return (stack != null && stack.isVisible()) ? stack : null;
     }
 
     /**
@@ -633,7 +633,7 @@
      */
     TaskStack getDockedStackVisibleForUserLocked() {
         final TaskStack stack = mService.mStackIdToStack.get(DOCKED_STACK_ID);
-        return (stack != null && stack.isVisibleLocked(true /* ignoreKeyguard */)) ? stack : null;
+        return (stack != null && stack.isVisible(true /* ignoreKeyguard */)) ? stack : null;
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index cd576734..de8e5ac 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -541,7 +541,7 @@
         final ArrayList<Task> homeStackTasks = homeStack.getTasks();
         final Task topHomeStackTask = homeStackTasks.get(homeStackTasks.size() - 1);
         final boolean homeVisible = homeTask.getTopVisibleAppToken() != null;
-        final boolean homeBehind = (fullscreenStack != null && fullscreenStack.isVisibleLocked())
+        final boolean homeBehind = (fullscreenStack != null && fullscreenStack.isVisible())
                 || (homeStackTasks.size() > 1 && topHomeStackTask != homeTask);
         // If the home task is an on-top launcher, we don't want to minimize the docked stack.
         // Instead we want everything underneath that was visible to remain visible.
@@ -639,7 +639,7 @@
         final ArrayList<TaskStack> stacks = mDisplayContent.getStacks();
         for (int i = stacks.size() - 1; i >= 0; --i) {
             final TaskStack stack = stacks.get(i);
-            if (stack.isVisibleLocked() && stack.isAdjustedForIme()) {
+            if (stack.isVisible() && stack.isAdjustedForIme()) {
                 stack.beginImeAdjustAnimation();
             }
         }
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 3451333..4241b32 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -304,9 +304,9 @@
             return false;
         }
         if ((boundsChanged & BOUNDS_CHANGE_SIZE) == BOUNDS_CHANGE_SIZE) {
-            resizeWindows();
+            onResize();
         } else {
-            setMovedByResize();
+            onMovedByResize();
         }
         return true;
     }
@@ -469,14 +469,14 @@
         }
     }
 
-    void resetDragResizingChangeReported() {
+    private void resetDragResizingChangeReported() {
         for (int activityNdx = mAppTokens.size() - 1; activityNdx >= 0; --activityNdx) {
             mAppTokens.get(activityNdx).resetDragResizingChangeReported();
         }
     }
 
     boolean isDragResizing() {
-        return mDragResizing || (mStack != null && mStack.isDragResizing());
+        return mDragResizing;
     }
 
     int getDragResizeMode() {
@@ -493,10 +493,12 @@
         }
     }
 
-    void detachDisplay() {
+    boolean detachFromDisplay() {
+        boolean didSomething = false;
         for (int i = mAppTokens.size() - 1; i >= 0; --i) {
-            mAppTokens.get(i).detachDisplay();
+            didSomething |= mAppTokens.get(i).detachFromDisplay();
         }
+        return didSomething;
     }
 
     void updateDisplayInfo(final DisplayContent displayContent) {
@@ -534,15 +536,15 @@
         }
     }
 
-    void resizeWindows() {
+    private void onResize() {
         for (int activityNdx = mAppTokens.size() - 1; activityNdx >= 0; --activityNdx) {
-            mAppTokens.get(activityNdx).resizeWindows();
+            mAppTokens.get(activityNdx).onResize();
         }
     }
 
-    void setMovedByResize() {
+    private void onMovedByResize() {
         for (int i = mAppTokens.size() - 1; i >= 0; --i) {
-            mAppTokens.get(i).setMovedByResize();
+            mAppTokens.get(i).onMovedByResize();
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 254a0d3..21fc08b 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -113,9 +113,6 @@
     /** Detach this stack from its display when animation completes. */
     boolean mDeferDetach;
 
-    // Whether the stack and all its tasks is currently being drag-resized
-    private boolean mDragResizing;
-
     private final Rect mTmpAdjustedBounds = new Rect();
     private boolean mAdjustedForIme;
     private boolean mImeGoingAway;
@@ -656,7 +653,7 @@
             throw new IllegalStateException(
                     "Calling getStackDockedModeBoundsLocked() when there is no docked stack.");
         }
-        if (!ignoreVisibility && !dockedStack.isVisibleLocked()) {
+        if (!ignoreVisibility && !dockedStack.isVisible()) {
             // The docked stack is being dismissed, but we caught before it finished being
             // dismissed. In that case we want to treat it as if it is not occupying any space and
             // let others occupy the whole display.
@@ -762,14 +759,16 @@
                 1 /*allowResizeInDockedMode*/, bounds).sendToTarget();
     }
 
-    void detachDisplay() {
+    boolean detachFromDisplay() {
         EventLog.writeEvent(EventLogTags.WM_STACK_REMOVED, mStackId);
 
+        boolean didSomething = false;
         for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
-            mTasks.get(taskNdx).detachDisplay();
+            didSomething |= mTasks.get(taskNdx).detachFromDisplay();
         }
 
         close();
+        return didSomething;
     }
 
     void resetAnimationBackgroundAnimator() {
@@ -846,7 +845,7 @@
             mAdjustImeAmount = adjustAmount;
             mAdjustDividerAmount = adjustDividerAmount;
             updateAdjustedBounds();
-            return isVisibleLocked(true /* ignoreKeyguard */);
+            return isVisible(true /* ignoreKeyguard */);
         } else {
             return false;
         }
@@ -882,7 +881,7 @@
         if (minimizeAmount != mMinimizeAmount) {
             mMinimizeAmount = minimizeAmount;
             updateAdjustedBounds();
-            return isVisibleLocked(true /* ignoreKeyguard*/);
+            return isVisible(true /* ignoreKeyguard */);
         } else {
             return false;
         }
@@ -1188,11 +1187,11 @@
         }
     }
 
-    boolean isVisibleLocked() {
-        return isVisibleLocked(false /* ignoreKeyguard */);
+    boolean isVisible() {
+        return isVisible(false /* ignoreKeyguard */);
     }
 
-    boolean isVisibleLocked(boolean ignoreKeyguard) {
+    boolean isVisible(boolean ignoreKeyguard) {
         final boolean keyguardOn = mService.mPolicy.isKeyguardShowingOrOccluded()
                 && !mService.mAnimator.mKeyguardGoingAway;
         if (!ignoreKeyguard && keyguardOn && !StackId.isAllowedOverLockscreen(mStackId)) {
@@ -1212,20 +1211,6 @@
         return false;
     }
 
-    boolean isDragResizing() {
-        return mDragResizing;
-    }
-
-    void setDragResizingLocked(boolean resizing) {
-        if (mDragResizing == resizing) {
-            return;
-        }
-        mDragResizing = resizing;
-        for (int i = mTasks.size() - 1; i >= 0 ; i--) {
-            mTasks.get(i).resetDragResizingChangeReported();
-        }
-    }
-
     @Override  // AnimatesBounds
     public boolean setSize(Rect bounds) {
         synchronized (mService.mWindowMap) {
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index fc4fdfa..fd6994c 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -92,6 +92,84 @@
         return false;
     }
 
+    void setWaitingForDrawnIfResizingChanged() {
+        for (int i = mChildren.size() - 1; i >= 0; --i) {
+            final WindowContainer wc = mChildren.get(i);
+            wc.setWaitingForDrawnIfResizingChanged();
+        }
+    }
+
+    void onResize() {
+        for (int i = mChildren.size() - 1; i >= 0; --i) {
+            final WindowContainer wc = mChildren.get(i);
+            wc.onResize();
+        }
+    }
+
+    void onMovedByResize() {
+        for (int i = mChildren.size() - 1; i >= 0; --i) {
+            final WindowContainer wc = mChildren.get(i);
+            wc.onMovedByResize();
+        }
+    }
+
+    void resetDragResizingChangeReported() {
+        for (int i = mChildren.size() - 1; i >= 0; --i) {
+            final WindowContainer wc = mChildren.get(i);
+            wc.resetDragResizingChangeReported();
+        }
+    }
+
+    boolean detachFromDisplay() {
+        boolean didSomething = false;
+        for (int i = mChildren.size() - 1; i >= 0; --i) {
+            final WindowContainer wc = mChildren.get(i);
+            didSomething |= wc.detachFromDisplay();
+        }
+        return didSomething;
+    }
+
+    void forceWindowsScaleableInTransaction(boolean force) {
+        for (int i = mChildren.size() - 1; i >= 0; --i) {
+            final WindowContainer wc = mChildren.get(i);
+            wc.forceWindowsScaleableInTransaction(force);
+        }
+    }
+
+    boolean isAnimating() {
+        for (int j = mChildren.size() - 1; j >= 0; j--) {
+            final WindowContainer wc = mChildren.get(j);
+            if (wc.isAnimating()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    void sendAppVisibilityToClients() {
+        for (int i = mChildren.size() - 1; i >= 0; --i) {
+            final WindowContainer wc = mChildren.get(i);
+            wc.sendAppVisibilityToClients();
+        }
+    }
+
+    void setVisibleBeforeClientHidden() {
+        for (int i = mChildren.size() - 1; i >= 0; --i) {
+            final WindowContainer wc = mChildren.get(i);
+            wc.setVisibleBeforeClientHidden();
+        }
+    }
+
+    boolean isVisible() {
+        for (int i = mChildren.size() - 1; i >= 0; --i) {
+            final WindowContainer wc = mChildren.get(i);
+            if (wc.isVisible()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     /** Returns the top child container or this container if there are no children. */
     WindowContainer getTop() {
         return mChildren.isEmpty() ? this : mChildren.peekLast();
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index d4750e7..851f8d8 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -4011,7 +4011,7 @@
 
     boolean isStackVisibleLocked(int stackId) {
         final TaskStack stack = mStackIdToStack.get(stackId);
-        return (stack != null && stack.isVisibleLocked());
+        return (stack != null && stack.isVisible());
     }
 
     public void setDockedStackCreateState(int mode, Rect bounds) {
@@ -4081,7 +4081,9 @@
 
     void detachStackLocked(DisplayContent displayContent, TaskStack stack) {
         displayContent.detachStack(stack);
-        stack.detachDisplay();
+        if (stack.detachFromDisplay()) {
+            mWindowPlacerLocked.requestTraversal();
+        }
         if (stack.mStackId == DOCKED_STACK_ID) {
             getDefaultDisplayContentLocked().mDividerControllerLocked
                     .notifyDockedStackExistsChanged(false);
@@ -4225,7 +4227,7 @@
                         + " not found.");
             }
             if (stack.setBounds(bounds, configs, taskBounds, taskTempInsetBounds)
-                    && stack.isVisibleLocked()) {
+                    && stack.isVisible()) {
                 stack.getDisplayContent().layoutNeeded = true;
                 mWindowPlacerLocked.performSurfacePlacement();
             }
@@ -6792,7 +6794,7 @@
             for (int i = stacks.size() - 1; i >= 0; --i) {
                 final TaskStack stack = stacks.get(i);
                 final boolean isDockedOnBottom = stack.getDockSide() == DOCKED_BOTTOM;
-                if (stack.isVisibleLocked() && (imeOnBottom || isDockedOnBottom)) {
+                if (stack.isVisible() && (imeOnBottom || isDockedOnBottom)) {
                     stack.setAdjustedForIme(imeWin, imeOnBottom && imeHeightChanged);
                 } else {
                     stack.resetAdjustedForIme(false);
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index dea06a9..2c359fc 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1172,6 +1172,7 @@
 
     // TODO: Sigh...another is visible method...tried to consolidate with other isVisible methods
     // below, but failed. Need to figure-out a good way to handle this long term...
+    @Override
     boolean isVisible() {
         // If we're animating with a saved surface, we're already visible.
         // Return true so that the alpha doesn't get cleared.
@@ -1181,13 +1182,7 @@
             return true;
         }
 
-        for (int i = mChildren.size() - 1; i >= 0; --i) {
-            final WindowState c = (WindowState) mChildren.get(i);
-            if (c.isVisible()) {
-                return true;
-            }
-        }
-        return false;
+        return super.isVisible();
     }
 
     /**
@@ -1427,14 +1422,11 @@
                 && (mAppToken == null || mAppToken.mAppAnimator.animation == null);
     }
 
-    void setMovedByResize() {
-        if (DEBUG_RESIZE) Slog.d(TAG, "setMovedByResize: Moving " + this);
+    @Override
+    void onMovedByResize() {
+        if (DEBUG_RESIZE) Slog.d(TAG, "onMovedByResize: Moving " + this);
         mMovedByResize = true;
-
-        for (int i = mChildren.size() - 1; i >= 0; --i) {
-            final WindowState c = (WindowState) mChildren.get(i);
-            c.setMovedByResize();
-        }
+        super.onMovedByResize();
     }
 
     boolean onAppVisibilityChanged(boolean visible, boolean runningAppAnimation) {
@@ -1499,14 +1491,15 @@
         return changed;
     }
 
-    void addToResizingList() {
+    @Override
+    void onResize() {
         // Some windows won't go through the resizing process, if they don't have a surface, so
         // destroy all saved surfaces here.
         destroySavedSurface();
 
         final ArrayList<WindowState> resizingWindows = mService.mResizingWindows;
         if (mHasSurface && !resizingWindows.contains(this)) {
-            if (DEBUG_RESIZE) Slog.d(TAG, "resizeWindows: Resizing " + this);
+            if (DEBUG_RESIZE) Slog.d(TAG, "onResize: Resizing " + this);
             resizingWindows.add(this);
 
             // If we are not drag resizing, force recreating of a new surface so updating
@@ -1529,10 +1522,7 @@
             mResizedWhileGone = true;
         }
 
-        for (int i = mChildren.size() - 1; i >= 0; --i) {
-            final WindowState c = (WindowState) mChildren.get(i);
-            c.addToResizingList();
-        }
+        super.onResize();
     }
 
     void onUnfreezeBounds() {
@@ -1618,15 +1608,13 @@
         }
     }
 
+    @Override
     void forceWindowsScaleableInTransaction(boolean force) {
         if (mWinAnimator != null && mWinAnimator.hasSurface()) {
             mWinAnimator.mSurfaceController.forceScaleableInTransaction(force);
         }
 
-        for (int i = mChildren.size() - 1; i >= 0; --i) {
-            final WindowState c = (WindowState) mChildren.get(i);
-            c.forceWindowsScaleableInTransaction(force);
-        }
+        super.forceWindowsScaleableInTransaction(force);
     }
 
     @Override
@@ -1815,6 +1803,15 @@
         Binder.restoreCallingIdentity(origId);
     }
 
+    @Override
+    boolean detachFromDisplay() {
+        // We are in the middle of changing the state of displays/stacks/tasks. We need
+        // to finish that, before we let layout interfere with it.
+        // Also removes child windows.
+        removeIfPossible();
+        return true;
+    }
+
     private void setupWindowForRemoveOnExit() {
         mRemoveOnExit = true;
         setDisplayLayoutNeeded();
@@ -2376,17 +2373,12 @@
         return mAnimatingWithSavedSurface;
     }
 
+    @Override
     boolean isAnimating() {
         if (mWinAnimator.isAnimationSet() || mAnimatingExit) {
             return true;
         }
-        for (int i = mChildren.size() - 1; i >= 0; --i) {
-            final WindowState c = (WindowState) mChildren.get(i);
-            if (c.isAnimating()) {
-                return true;
-            }
-        }
-        return false;
+        return super.isAnimating();
     }
 
     boolean isAnimatingInvisibleWithSavedSurface() {
@@ -2440,12 +2432,10 @@
         }
     }
 
-    void sendAppVisibilityToClients(boolean clientHidden) {
-        for (int i = mChildren.size() - 1; i >= 0; --i) {
-            final WindowState c = (WindowState) mChildren.get(i);
-            c.sendAppVisibilityToClients(clientHidden);
-        }
+    void sendAppVisibilityToClients() {
+        super.sendAppVisibilityToClients();
 
+        final boolean clientHidden = mAppToken.clientHidden;
         if (mAttrs.type == TYPE_APPLICATION_STARTING && clientHidden) {
             // Don't hide the starting window.
             return;
@@ -2463,10 +2453,7 @@
         mWasVisibleBeforeClientHidden |=
                 (mViewVisibility == View.VISIBLE || mAnimatingWithSavedSurface);
 
-        for (int i = mChildren.size() - 1; i >= 0; --i) {
-            final WindowState c = (WindowState) mChildren.get(i);
-            c.setVisibleBeforeClientHidden();
-        }
+        super.setVisibleBeforeClientHidden();
     }
 
     public void clearWasVisibleBeforeClientHidden() {
@@ -3028,14 +3015,12 @@
         return mDragResizing != computeDragResizing();
     }
 
+    @Override
     void setWaitingForDrawnIfResizingChanged() {
         if (isDragResizeChanged()) {
             mService.mWaitingForDrawn.add(this);
         }
-        for (int i = mChildren.size() - 1; i >= 0; --i) {
-            final WindowState c = (WindowState) mChildren.get(i);
-            c.setWaitingForDrawnIfResizingChanged();
-        }
+        super.setWaitingForDrawnIfResizingChanged();
     }
 
     /**
@@ -3048,12 +3033,10 @@
     /**
      * Resets the state whether we reported a drag resize change to the app.
      */
+    @Override
     void resetDragResizingChangeReported() {
         mDragResizingChangeReported = false;
-        for (int i = mChildren.size() - 1; i >= 0; --i) {
-            final WindowState c = (WindowState) mChildren.get(i);
-            c.resetDragResizingChangeReported();
-        }
+        super.resetDragResizingChangeReported();
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 553b056..5f9bb9a 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -42,12 +42,11 @@
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
 
 /**
- * Container of a set of related windows in the window manager.  Often this
- * is an AppWindowToken, which is the handle for an Activity that it uses
- * to display windows.  For nested windows, there is a WindowToken created for
- * the parent window to manage its children.
+ * Container of a set of related windows in the window manager. Often this is an AppWindowToken,
+ * which is the handle for an Activity that it uses to display windows. For nested windows, there is
+ * a WindowToken created for the parent window to manage its children.
  */
-class WindowToken {
+class WindowToken extends WindowContainer {
     private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowToken" : TAG_WM;
 
     // The window manager!
@@ -66,9 +65,6 @@
     // For printing.
     String stringName;
 
-    // All of the windows associated with this token.
-    protected final WindowList windows = new WindowList();
-
     // Is key dispatching paused for this token?
     boolean paused = false;
 
@@ -95,12 +91,12 @@
     }
 
     void removeAllWindows() {
-        for (int i = windows.size() - 1; i >= 0; --i) {
-            final WindowState win = windows.get(i);
+        for (int i = mChildren.size() - 1; i >= 0; --i) {
+            final WindowState win = (WindowState) mChildren.get(i);
             if (DEBUG_WINDOW_MOVEMENT) Slog.w(TAG_WM, "removeAllWindows: removing win=" + win);
             win.removeIfPossible();
         }
-        windows.clear();
+        mChildren.clear();
     }
 
     void setExiting() {
@@ -108,13 +104,13 @@
             return;
         }
 
-        final int count = windows.size();
+        final int count = mChildren.size();
         boolean changed = false;
         boolean delayed = false;
         DisplayContent displayContent = null;
 
         for (int i = 0; i < count; i++) {
-            final WindowState win = windows.get(i);
+            final WindowState win = (WindowState) mChildren.get(i);
             if (win.mWinAnimator.isAnimationSet()) {
                 delayed = true;
                 // TODO: This is technically wrong as a token can have windows on multi-displays
@@ -138,8 +134,8 @@
 
     int adjustAnimLayer(int adj) {
         int highestAnimLayer = -1;
-        for (int j = windows.size() - 1; j >= 0; j--) {
-            final WindowState w = windows.get(j);
+        for (int j = mChildren.size() - 1; j >= 0; j--) {
+            final WindowState w = (WindowState) mChildren.get(j);
             final int winHighestAnimLayer = w.adjustAnimLayer(adj);
             if (winHighestAnimLayer > highestAnimLayer) {
                 highestAnimLayer = winHighestAnimLayer;
@@ -151,11 +147,12 @@
         return highestAnimLayer;
     }
 
-    private WindowState getTopWindow() {
-        if (windows.isEmpty()) {
+    /* package level access for test. */
+    WindowState getTopWindow() {
+        if (mChildren.isEmpty()) {
             return null;
         }
-        return (WindowState) windows.get(windows.size() - 1).getTop();
+        return (WindowState) mChildren.get(mChildren.size() - 1).getTop();
     }
 
     /**
@@ -163,9 +160,10 @@
      * @param target The window to search for.
      * @return The index of win in windows or of the window that is an ancestor of win.
      */
-    private int getWindowIndex(WindowState target) {
-        for (int i = windows.size() - 1; i >= 0; --i) {
-            final WindowState w = windows.get(i);
+    /* package level access for test. */
+    int getWindowIndex(WindowState target) {
+        for (int i = mChildren.size() - 1; i >= 0; --i) {
+            final WindowState w = (WindowState) mChildren.get(i);
             if (w == target || w.hasChild(target)) {
                 return i;
             }
@@ -250,9 +248,9 @@
             } else {
                 win.addNonAppWindowToList();
             }
-            if (!windows.contains(win)) {
+            if (!mChildren.contains(win)) {
                 if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Adding " + win + " to " + this);
-                windows.add(tokenWindowsPos, win);
+                mChildren.add(tokenWindowsPos, win);
             }
         } else {
             addChildWindow(win);
@@ -424,9 +422,9 @@
     }
 
     int reAddAppWindows(DisplayContent displayContent, int index) {
-        final int count = windows.size();
+        final int count = mChildren.size();
         for (int i = 0; i < count; i++) {
-            final WindowState win = windows.get(i);
+            final WindowState win = (WindowState) mChildren.get(i);
             final DisplayContent winDisplayContent = win.getDisplayContent();
             if (winDisplayContent == displayContent || winDisplayContent == null) {
                 win.mDisplayContent = displayContent;
@@ -441,9 +439,9 @@
      * ordering the windows in mWindows
      */
     private int findIdxBasedOnAppTokens(WindowState win) {
-        WindowList windows = win.getWindowList();
+        final WindowList windows = win.getWindowList();
         for(int j = windows.size() - 1; j >= 0; j--) {
-            WindowState wentry = windows.get(j);
+            final WindowState wentry = windows.get(j);
             if(wentry.mAppToken == win.mAppToken) {
                 return j;
             }
@@ -453,10 +451,10 @@
 
     /** Return the first window in the token window list that isn't a starting window or null. */
     WindowState getFirstNonStartingWindow() {
-        final int count = windows.size();
+        final int count = mChildren.size();
         // We only care about parent windows so no need to loop through child windows.
         for (int i = 0; i < count; i++) {
-            final WindowState w = windows.get(i);
+            final WindowState w = (WindowState) mChildren.get(i);
             if (w.mAttrs.type != TYPE_APPLICATION_STARTING) {
                 return w;
             }
@@ -466,17 +464,17 @@
 
     @CallSuper
     void removeWindow(WindowState win) {
-        windows.remove(win);
+        mChildren.remove(win);
     }
 
     /** Returns true if the token windows list is empty. */
     boolean isEmpty() {
-        return windows.isEmpty();
+        return mChildren.isEmpty();
     }
 
     WindowState getReplacingWindow() {
-        for (int i = windows.size() - 1; i >= 0; i--) {
-            final WindowState win = windows.get(i);
+        for (int i = mChildren.size() - 1; i >= 0; i--) {
+            final WindowState win = (WindowState) mChildren.get(i);
             final WindowState replacing = win.getReplacingWindow();
             if (replacing != null) {
                 return replacing;
@@ -486,8 +484,8 @@
     }
 
     void hideWallpaperToken(boolean wasDeferred, String reason) {
-        for (int j = windows.size() - 1; j >= 0; j--) {
-            final WindowState wallpaper = windows.get(j);
+        for (int j = mChildren.size() - 1; j >= 0; j--) {
+            final WindowState wallpaper = (WindowState) mChildren.get(j);
             wallpaper.hideWallpaperWindow(wasDeferred, reason);
         }
         hidden = true;
@@ -495,8 +493,8 @@
 
     void sendWindowWallpaperCommand(
             String action, int x, int y, int z, Bundle extras, boolean sync) {
-        for (int wallpaperNdx = windows.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
-            WindowState wallpaper = windows.get(wallpaperNdx);
+        for (int wallpaperNdx = mChildren.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
+            final WindowState wallpaper = (WindowState) mChildren.get(wallpaperNdx);
             try {
                 wallpaper.mClient.dispatchWallpaperCommand(action, x, y, z, extras, sync);
                 // We only want to be synchronous with one wallpaper.
@@ -508,8 +506,8 @@
 
     void updateWallpaperOffset(int dw, int dh, boolean sync) {
         final WallpaperController wallpaperController = mService.mWallpaperControllerLocked;
-        for (int wallpaperNdx = windows.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
-            WindowState wallpaper = windows.get(wallpaperNdx);
+        for (int wallpaperNdx = mChildren.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
+            final WindowState wallpaper = (WindowState) mChildren.get(wallpaperNdx);
             if (wallpaperController.updateWallpaperOffset(wallpaper, dw, dh, sync)) {
                 final WindowStateAnimator winAnimator = wallpaper.mWinAnimator;
                 winAnimator.computeShownFrameLocked();
@@ -529,8 +527,8 @@
         }
 
         final WallpaperController wallpaperController = mService.mWallpaperControllerLocked;
-        for (int wallpaperNdx = windows.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
-            WindowState wallpaper = windows.get(wallpaperNdx);
+        for (int wallpaperNdx = mChildren.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
+            final WindowState wallpaper = (WindowState) mChildren.get(wallpaperNdx);
             if (visible) {
                 wallpaperController.updateWallpaperOffset(wallpaper, dw, dh, false);
             }
@@ -552,8 +550,8 @@
         }
 
         final WallpaperController wallpaperController = mService.mWallpaperControllerLocked;
-        for (int wallpaperNdx = windows.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
-            final WindowState wallpaper = windows.get(wallpaperNdx);
+        for (int wallpaperNdx = mChildren.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
+            final WindowState wallpaper = (WindowState) mChildren.get(wallpaperNdx);
 
             if (visible) {
                 wallpaperController.updateWallpaperOffset(wallpaper, dw, dh, false);
@@ -628,8 +626,8 @@
     }
 
     boolean hasVisibleNotDrawnWallpaper() {
-        for (int j = windows.size() - 1; j >= 0; --j) {
-            final WindowState wallpaper = windows.get(j);
+        for (int j = mChildren.size() - 1; j >= 0; --j) {
+            final WindowState wallpaper = (WindowState) mChildren.get(j);
             if (wallpaper.hasVisibleNotDrawnWallpaper()) {
                 return true;
             }
@@ -639,8 +637,8 @@
 
     int getHighestAnimLayer() {
         int highest = -1;
-        for (int j = 0; j < windows.size(); j++) {
-            final WindowState w = windows.get(j);
+        for (int j = 0; j < mChildren.size(); j++) {
+            final WindowState w = (WindowState) mChildren.get(j);
             final int wLayer = w.getHighestAnimLayer();
             if (wLayer > highest) {
                 highest = wLayer;
@@ -656,7 +654,7 @@
     }
 
     void dump(PrintWriter pw, String prefix) {
-        pw.print(prefix); pw.print("windows="); pw.println(windows);
+        pw.print(prefix); pw.print("windows="); pw.println(mChildren);
         pw.print(prefix); pw.print("windowType="); pw.print(windowType);
                 pw.print(" hidden="); pw.print(hidden);
                 pw.print(" hasVisible="); pw.println(hasVisible);