Cleaned-up RootWindowContainer.applySurfaceChangesTransaction

- Move functionality for determining interesting and all drawn states
of an app token based on the current window we are processing into
AppWindowToken.updateDrawnWindowStates() since it is mostly touching
AppWindowToken variables. Some of the fields can now be made private.
- Removed WindowContainer.updateAllDrawn() and related overrides. We
now have RootWindowContainer collect the app tokens that need to be
processed and call them directly.
- Move code to report window move to client into
WindowState.reportWindowMovedIfNeeded().
- Move WMS.updateResizingWindows() functionality to
WindowState.updateResizingWindow() as it mostly updates window state
internals.

Bug: 31794753
Test: Manual testing and existing unit tests pass.
Change-Id: I7588217d05d3e8971ce61795cb8568d835779c5e
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 9c5392e..2187d41 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -35,6 +35,7 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.WindowManagerService.H.NOTIFY_ACTIVITY_DRAWN;
+import static com.android.server.wm.WindowManagerService.H.NOTIFY_STARTING_WINDOW_DRAWN;
 import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_NONE;
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
 import static com.android.server.wm.WindowManagerService.logWithStack;
@@ -91,19 +92,22 @@
     // an activity have been drawn, so they can be made visible together
     // at the same time.
     // initialize so that it doesn't match mTransactionSequence which is an int.
-    long lastTransactionSequence = Long.MIN_VALUE;
-    int numInterestingWindows;
-    int numDrawnWindows;
+    private long mLastTransactionSequence = Long.MIN_VALUE;
+    private int mNumInterestingWindows;
+    private int mNumDrawnWindows;
     boolean inPendingTransaction;
     boolean allDrawn;
     // Set to true when this app creates a surface while in the middle of an animation. In that
     // case do not clear allDrawn until the animation completes.
     boolean deferClearAllDrawn;
 
-    // These are to track the app's real drawing status if there were no saved surfaces.
+    /**
+     * These are to track the app's real drawing status if there were no saved surfaces.
+     * @see #updateDrawnWindowStates
+     */
     boolean allDrawnExcludingSaved;
-    int numInterestingWindowsExcludingSaved;
-    int numDrawnWindowsExcludingSaved;
+    private int mNumInterestingWindowsExcludingSaved;
+    private int mNumDrawnWindowsExcludingSaved;
 
     // Is this window's surface needed?  This is almost like hidden, except
     // it will sometimes be true a little earlier: when the token has
@@ -118,7 +122,7 @@
     boolean reportedVisible;
 
     // Last drawn state we reported to the app token.
-    boolean reportedDrawn;
+    private boolean reportedDrawn;
 
     // Set to true when the token has been removed from the window mgr.
     boolean removed;
@@ -146,7 +150,7 @@
 
     boolean mAppStopped;
     int mRotationAnimationHint;
-    int mPendingRelaunchCount;
+    private int mPendingRelaunchCount;
 
     private ArrayList<WindowSurfaceController.SurfaceControlWithBackground> mSurfaceViewBackgrounds =
         new ArrayList<>();
@@ -1037,7 +1041,7 @@
             stopFreezingScreen(false, true);
             if (DEBUG_ORIENTATION) Slog.i(TAG,
                     "Setting mOrientationChangeComplete=true because wtoken " + this
-                    + " numInteresting=" + numInterestingWindows + " numDrawn=" + numDrawnWindows);
+                    + " numInteresting=" + mNumInterestingWindows + " numDrawn=" + mNumDrawnWindows);
             // This will set mOrientationChangeComplete and cause a pass through layout.
             setAppLayoutChanges(FINISH_LAYOUT_REDO_WALLPAPER,
                     "checkAppWindowsReadyToShow: freezingScreen", displayId);
@@ -1051,30 +1055,28 @@
         }
     }
 
-    @Override
-    void updateAllDrawn(int displayId) {
-        final DisplayContent displayContent = mService.mRoot.getDisplayContentOrCreate(displayId);
-
+    void updateAllDrawn(DisplayContent dc) {
         if (!allDrawn) {
-            final int numInteresting = numInterestingWindows;
-            if (numInteresting > 0 && numDrawnWindows >= numInteresting) {
+            final int numInteresting = mNumInterestingWindows;
+            if (numInteresting > 0 && mNumDrawnWindows >= numInteresting) {
                 if (DEBUG_VISIBILITY) Slog.v(TAG, "allDrawn: " + this
-                        + " interesting=" + numInteresting + " drawn=" + numDrawnWindows);
+                        + " interesting=" + numInteresting + " drawn=" + mNumDrawnWindows);
                 allDrawn = true;
                 // Force an additional layout pass where
                 // WindowStateAnimator#commitFinishDrawingLocked() will call performShowLocked().
-                displayContent.setLayoutNeeded();
+                dc.setLayoutNeeded();
                 mService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN, token).sendToTarget();
             }
         }
+
         if (!allDrawnExcludingSaved) {
-            int numInteresting = numInterestingWindowsExcludingSaved;
-            if (numInteresting > 0 && numDrawnWindowsExcludingSaved >= numInteresting) {
+            int numInteresting = mNumInterestingWindowsExcludingSaved;
+            if (numInteresting > 0 && mNumDrawnWindowsExcludingSaved >= numInteresting) {
                 if (DEBUG_VISIBILITY) Slog.v(TAG, "allDrawnExcludingSaved: " + this
                         + " interesting=" + numInteresting
-                        + " drawn=" + numDrawnWindowsExcludingSaved);
+                        + " drawn=" + mNumDrawnWindowsExcludingSaved);
                 allDrawnExcludingSaved = true;
-                displayContent.setLayoutNeeded();
+                dc.setLayoutNeeded();
                 if (isAnimatingInvisibleWithSavedSurface()
                         && !mService.mFinishedEarlyAnim.contains(this)) {
                     mService.mFinishedEarlyAnim.add(this);
@@ -1083,6 +1085,87 @@
         }
     }
 
+    /**
+     * Updated this app token tracking states for interesting and drawn windows based on the window.
+     *
+     * @return Returns true if the input window is considered interesting and drawn while all the
+     *         windows in this app token where not considered drawn as of the last pass.
+     */
+    boolean updateDrawnWindowStates(WindowState w) {
+        if (DEBUG_STARTING_WINDOW && w == startingWindow) {
+            Slog.d(TAG, "updateWindows: starting " + w + " isOnScreen=" + w.isOnScreen()
+                    + " allDrawn=" + allDrawn + " freezingScreen=" + mAppAnimator.freezingScreen);
+        }
+
+        if (allDrawn && allDrawnExcludingSaved && !mAppAnimator.freezingScreen) {
+            return false;
+        }
+
+        if (mLastTransactionSequence != mService.mTransactionSequence) {
+            mLastTransactionSequence = mService.mTransactionSequence;
+            mNumInterestingWindows = mNumDrawnWindows = 0;
+            mNumInterestingWindowsExcludingSaved = 0;
+            mNumDrawnWindowsExcludingSaved = 0;
+            startingDisplayed = false;
+        }
+
+        final WindowStateAnimator winAnimator = w.mWinAnimator;
+
+        boolean isInterestingAndDrawn = false;
+
+        if (!allDrawn && w.mightAffectAllDrawn(false /* visibleOnly */)) {
+            if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
+                Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw()
+                        + ", isAnimationSet=" + winAnimator.isAnimationSet());
+                if (!w.isDrawnLw()) {
+                    Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceController
+                            + " pv=" + w.mPolicyVisibility
+                            + " mDrawState=" + winAnimator.drawStateToString()
+                            + " ph=" + w.isParentWindowHidden() + " th=" + hiddenRequested
+                            + " a=" + winAnimator.mAnimating);
+                }
+            }
+
+            if (w != startingWindow) {
+                if (w.isInteresting()) {
+                    mNumInterestingWindows++;
+                    if (w.isDrawnLw()) {
+                        mNumDrawnWindows++;
+
+                        if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG, "tokenMayBeDrawn: "
+                                + this + " w=" + w + " numInteresting=" + mNumInterestingWindows
+                                + " freezingScreen=" + mAppAnimator.freezingScreen
+                                + " mAppFreezing=" + w.mAppFreezing);
+
+                        isInterestingAndDrawn = true;
+                    }
+                }
+            } else if (w.isDrawnLw()) {
+                mService.mH.sendEmptyMessage(NOTIFY_STARTING_WINDOW_DRAWN);
+                startingDisplayed = true;
+            }
+        }
+
+        if (!allDrawnExcludingSaved && w.mightAffectAllDrawn(true /* visibleOnly */)) {
+            if (w != startingWindow && w.isInteresting()) {
+                mNumInterestingWindowsExcludingSaved++;
+                if (w.isDrawnLw() && !w.isAnimatingWithSavedSurface()) {
+                    mNumDrawnWindowsExcludingSaved++;
+
+                    if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) Slog.v(TAG,
+                            "tokenMayBeDrawnExcludingSaved: " + this + " w=" + w
+                            + " numInteresting=" + mNumInterestingWindowsExcludingSaved
+                            + " freezingScreen=" + mAppAnimator.freezingScreen
+                            + " mAppFreezing=" + w.mAppFreezing);
+
+                    isInterestingAndDrawn = true;
+                }
+            }
+        }
+
+        return isInterestingAndDrawn;
+    }
+
     @Override
     void stepAppWindowsAnimation(long currentTime, int displayId) {
         mAppAnimator.wasAnimating = mAppAnimator.animating;
@@ -1144,11 +1227,11 @@
         if (mAppStopped) {
             pw.print(prefix); pw.print("mAppStopped="); pw.println(mAppStopped);
         }
-        if (numInterestingWindows != 0 || numDrawnWindows != 0
+        if (mNumInterestingWindows != 0 || mNumDrawnWindows != 0
                 || allDrawn || mAppAnimator.allDrawn) {
-            pw.print(prefix); pw.print("numInterestingWindows=");
-                    pw.print(numInterestingWindows);
-                    pw.print(" numDrawnWindows="); pw.print(numDrawnWindows);
+            pw.print(prefix); pw.print("mNumInterestingWindows=");
+                    pw.print(mNumInterestingWindows);
+                    pw.print(" mNumDrawnWindows="); pw.print(mNumDrawnWindows);
                     pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
                     pw.print(" allDrawn="); pw.print(allDrawn);
                     pw.print(" (animator="); pw.print(mAppAnimator.allDrawn);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 34a7390..42e9e23 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -240,10 +240,6 @@
         super.checkAppWindowsReadyToShow(mDisplayId);
     }
 
-    void updateAllDrawn() {
-        super.updateAllDrawn(mDisplayId);
-    }
-
     void stepAppWindowsAnimation(long currentTime) {
         super.stepAppWindowsAnimation(currentTime, mDisplayId);
     }
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 219fd8e..1700bca 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -41,12 +41,12 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.LinkedList;
 
 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
 import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE;
 import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
 import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
@@ -65,7 +65,6 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_POWER;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
@@ -76,7 +75,6 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_KEEP_SCREEN_ON;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
-import static com.android.server.wm.WindowManagerService.H.NOTIFY_STARTING_WINDOW_DRAWN;
 import static com.android.server.wm.WindowManagerService.H.REPORT_LOSING_FOCUS;
 import static com.android.server.wm.WindowManagerService.H.SEND_NEW_CONFIGURATION;
 import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD;
@@ -136,6 +134,8 @@
 
     private final ArrayList<Integer> mChangedStackList = new ArrayList();
 
+    private final LinkedList<AppWindowToken> mTmpUpdateAllDrawn = new LinkedList();
+
     // State for the RemoteSurfaceTrace system used in testing. If this is enabled SurfaceControl
     // instances will be replaced with an instance that writes a binary representation of all
     // commands to mSurfaceTraceFd.
@@ -707,7 +707,7 @@
                 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
         mService.openSurfaceTransaction();
         try {
-            mService.mRoot.applySurfaceChangesTransaction(recoveringMemory, defaultDw, defaultDh);
+            applySurfaceChangesTransaction(recoveringMemory, defaultDw, defaultDh);
         } catch (RuntimeException e) {
             Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
         } finally {
@@ -990,7 +990,6 @@
         final int count = mChildren.size();
         for (int j = 0; j < count; ++j) {
             final DisplayContent dc = mChildren.get(j);
-            boolean updateAllDrawn = false;
             WindowList windows = dc.getWindowList();
             DisplayInfo displayInfo = dc.getDisplayInfo();
             final int displayId = dc.getDisplayId();
@@ -1003,6 +1002,7 @@
             mDisplayHasContent = false;
             mPreferredRefreshRate = 0;
             mPreferredModeId = 0;
+            mTmpUpdateAllDrawn.clear();
 
             int repeats = 0;
             do {
@@ -1086,45 +1086,14 @@
                 if (isDefaultDisplay && obscuredChanged && w.isVisibleLw()
                         && mService.mWallpaperControllerLocked.isWallpaperTarget(w)) {
                     // This is the wallpaper target and its obscured state changed... make sure the
-                    // current wallaper's visibility has been updated accordingly.
+                    // current wallpaper's visibility has been updated accordingly.
                     mService.mWallpaperControllerLocked.updateWallpaperVisibility();
                 }
 
+                w.handleWindowMovedIfNeeded();
+
                 final WindowStateAnimator winAnimator = w.mWinAnimator;
 
-                // If the window has moved due to its containing content frame changing, then
-                // notify the listeners and optionally animate it. Simply checking a change of
-                // position is not enough, because being move due to dock divider is not a trigger
-                // for animation.
-                if (w.hasMoved()) {
-                    // Frame has moved, containing content frame has also moved, and we're not
-                    // currently animating... let's do something.
-                    final int left = w.mFrame.left;
-                    final int top = w.mFrame.top;
-                    final boolean adjustedForMinimizedDockOrIme = task != null
-                            && (task.mStack.isAdjustedForMinimizedDockedStack()
-                            || task.mStack.isAdjustedForIme());
-                    if (mService.okToDisplay()
-                            && (w.mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
-                            && !w.isDragResizing() && !adjustedForMinimizedDockOrIme
-                            && (task == null || w.getTask().mStack.hasMovementAnimations())
-                            && !w.mWinAnimator.mLastHidden) {
-                        winAnimator.setMoveAnimation(left, top);
-                    }
-
-                    //TODO (multidisplay): Accessibility supported only for the default display.
-                    if (mService.mAccessibilityController != null
-                            && displayId == Display.DEFAULT_DISPLAY) {
-                        mService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
-                    }
-
-                    try {
-                        w.mClient.moved(left, top);
-                    } catch (RemoteException e) {
-                    }
-                    w.mMovedByResize = false;
-                }
-
                 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
                 w.mContentChanged = false;
 
@@ -1171,71 +1140,10 @@
                 }
 
                 final AppWindowToken atoken = w.mAppToken;
-                if (DEBUG_STARTING_WINDOW && atoken != null && w == atoken.startingWindow) {
-                    Slog.d(TAG, "updateWindows: starting " + w
-                            + " isOnScreen=" + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
-                            + " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
-                }
-                if (atoken != null && (!atoken.allDrawn || !atoken.allDrawnExcludingSaved
-                        || atoken.mAppAnimator.freezingScreen)) {
-                    if (atoken.lastTransactionSequence != mService.mTransactionSequence) {
-                        atoken.lastTransactionSequence = mService.mTransactionSequence;
-                        atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
-                        atoken.numInterestingWindowsExcludingSaved = 0;
-                        atoken.numDrawnWindowsExcludingSaved = 0;
-                        atoken.startingDisplayed = false;
-                    }
-                    if (!atoken.allDrawn && w.mightAffectAllDrawn(false /* visibleOnly */)) {
-                        if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
-                            Slog.v(TAG, "Eval win " + w + ": isDrawn="
-                                    + w.isDrawnLw()
-                                    + ", isAnimationSet=" + winAnimator.isAnimationSet());
-                            if (!w.isDrawnLw()) {
-                                Slog.v(TAG, "Not displayed: s="
-                                        + winAnimator.mSurfaceController
-                                        + " pv=" + w.mPolicyVisibility
-                                        + " mDrawState=" + winAnimator.drawStateToString()
-                                        + " ph=" + w.isParentWindowHidden()
-                                        + " th=" + atoken.hiddenRequested
-                                        + " a=" + winAnimator.mAnimating);
-                            }
-                        }
-                        if (w != atoken.startingWindow) {
-                            if (w.isInteresting()) {
-                                atoken.numInterestingWindows++;
-                                if (w.isDrawnLw()) {
-                                    atoken.numDrawnWindows++;
-                                    if (DEBUG_VISIBILITY || DEBUG_ORIENTATION)
-                                        Slog.v(TAG, "tokenMayBeDrawn: " + atoken
-                                                + " w=" + w + " numInteresting="
-                                                + atoken.numInterestingWindows
-                                                + " freezingScreen="
-                                                + atoken.mAppAnimator.freezingScreen
-                                                + " mAppFreezing=" + w.mAppFreezing);
-                                    updateAllDrawn = true;
-                                }
-                            }
-                        } else if (w.isDrawnLw()) {
-                            mService.mH.sendEmptyMessage(NOTIFY_STARTING_WINDOW_DRAWN);
-                            atoken.startingDisplayed = true;
-                        }
-                    }
-                    if (!atoken.allDrawnExcludingSaved
-                            && w.mightAffectAllDrawn(true /* visibleOnly */)) {
-                        if (w != atoken.startingWindow && w.isInteresting()) {
-                            atoken.numInterestingWindowsExcludingSaved++;
-                            if (w.isDrawnLw() && !w.isAnimatingWithSavedSurface()) {
-                                atoken.numDrawnWindowsExcludingSaved++;
-                                if (DEBUG_VISIBILITY || DEBUG_ORIENTATION)
-                                    Slog.v(TAG, "tokenMayBeDrawnExcludingSaved: " + atoken
-                                            + " w=" + w + " numInteresting="
-                                            + atoken.numInterestingWindowsExcludingSaved
-                                            + " freezingScreen="
-                                            + atoken.mAppAnimator.freezingScreen
-                                            + " mAppFreezing=" + w.mAppFreezing);
-                                updateAllDrawn = true;
-                            }
-                        }
+                if (atoken != null) {
+                    final boolean updateAllDrawn = atoken.updateDrawnWindowStates(w);
+                    if (updateAllDrawn && !mTmpUpdateAllDrawn.contains(atoken)) {
+                        mTmpUpdateAllDrawn.add(atoken);
                     }
                 }
 
@@ -1244,7 +1152,7 @@
                     focusDisplayed = true;
                 }
 
-                mService.updateResizingWindows(w);
+                w.updateResizingWindowIfNeeded();
             }
 
             mService.mDisplayManagerInternal.setDisplayProperties(displayId,
@@ -1255,10 +1163,11 @@
 
             dc.stopDimmingIfNeeded();
 
-            if (updateAllDrawn) {
+            while (!mTmpUpdateAllDrawn.isEmpty()) {
+                final AppWindowToken atoken = mTmpUpdateAllDrawn.removeLast();
                 // See if any windows have been drawn, so they (and others associated with them)
                 // can now be shown.
-                dc.updateAllDrawn();
+                atoken.updateAllDrawn(dc);
             }
         }
 
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 8777d88..902f4ae 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -381,19 +381,6 @@
         }
     }
 
-    /**
-     * Updates the current all drawn status for this container. That is all its children
-     * that should draw something have done so.
-     */
-    // TODO: The displayId shouldn't be needed as there shouldn't be a container on more than one
-    // display. Remove once we migrate DisplayContent to use WindowContainer.
-    void updateAllDrawn(int displayId) {
-        for (int i = mChildren.size() - 1; i >= 0; --i) {
-            final WindowContainer wc = mChildren.get(i);
-            wc.updateAllDrawn(displayId);
-        }
-    }
-
     /** Step currently ongoing animation for App window containers. */
     // TODO: The displayId shouldn't be needed as there shouldn't be a container on more than one
     // display. Remove once we migrate DisplayContent to use WindowContainer.
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 310ad5a..5970998 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -8048,108 +8048,6 @@
         return changes;
     }
 
-    void updateResizingWindows(final WindowState w) {
-        final WindowStateAnimator winAnimator = w.mWinAnimator;
-        if (w.mHasSurface && w.mLayoutSeq == mLayoutSeq && !w.isGoneForLayoutLw()) {
-            final Task task = w.getTask();
-            // In the case of stack bound animations, the window frames will update (unlike other
-            // animations which just modify various transformation properties). We don't want to
-            // notify the client of frame changes in this case. Not only is it a lot of churn, but
-            // the frame may not correspond to the surface size or the onscreen area at various
-            // phases in the animation, and the client will become sad and confused.
-            if (task != null && task.mStack.getBoundsAnimating()) {
-                return;
-            }
-            w.setReportResizeHints();
-            boolean configChanged = w.isConfigChanged();
-            if (DEBUG_CONFIGURATION && configChanged) {
-                Slog.v(TAG_WM, "Win " + w + " config changed: " + w.getConfiguration());
-            }
-            final boolean dragResizingChanged = w.isDragResizeChanged()
-                    && !w.isDragResizingChangeReported();
-
-            if (localLOGV) Slog.v(TAG_WM, "Resizing " + w + ": configChanged=" + configChanged
-                    + " dragResizingChanged=" + dragResizingChanged + " last=" + w.mLastFrame
-                    + " frame=" + w.mFrame);
-
-            // We update mLastFrame always rather than in the conditional with the
-            // last inset variables, because mFrameSizeChanged only tracks the
-            // width and height changing.
-            w.mLastFrame.set(w.mFrame);
-
-            if (w.mContentInsetsChanged
-                    || w.mVisibleInsetsChanged
-                    || winAnimator.mSurfaceResized
-                    || w.mOutsetsChanged
-                    || w.mFrameSizeChanged
-                    || configChanged
-                    || dragResizingChanged
-                    || !w.isResizedWhileNotDragResizingReported()) {
-                if (DEBUG_RESIZE || DEBUG_ORIENTATION) {
-                    Slog.v(TAG_WM, "Resize reasons for w=" + w + ": "
-                            + " contentInsetsChanged=" + w.mContentInsetsChanged
-                            + " " + w.mContentInsets.toShortString()
-                            + " visibleInsetsChanged=" + w.mVisibleInsetsChanged
-                            + " " + w.mVisibleInsets.toShortString()
-                            + " stableInsetsChanged=" + w.mStableInsetsChanged
-                            + " " + w.mStableInsets.toShortString()
-                            + " outsetsChanged=" + w.mOutsetsChanged
-                            + " " + w.mOutsets.toShortString()
-                            + " surfaceResized=" + winAnimator.mSurfaceResized
-                            + " configChanged=" + configChanged
-                            + " dragResizingChanged=" + dragResizingChanged
-                            + " resizedWhileNotDragResizingReported="
-                            + w.isResizedWhileNotDragResizingReported());
-                }
-
-                // If it's a dead window left on screen, and the configuration changed,
-                // there is nothing we can do about it. Remove the window now.
-                if (w.mAppToken != null && w.mAppDied) {
-                    w.mAppToken.removeDeadWindows();
-                    return;
-                }
-
-                w.mLastOverscanInsets.set(w.mOverscanInsets);
-                w.mLastContentInsets.set(w.mContentInsets);
-                w.mLastVisibleInsets.set(w.mVisibleInsets);
-                w.mLastStableInsets.set(w.mStableInsets);
-                w.mLastOutsets.set(w.mOutsets);
-                makeWindowFreezingScreenIfNeededLocked(w);
-                // If the orientation is changing, or we're starting or ending
-                // a drag resizing action, then we need to hold off on unfreezing
-                // the display until this window has been redrawn; to do that,
-                // we need to go through the process of getting informed by the
-                // application when it has finished drawing.
-                if (w.mOrientationChanging || dragResizingChanged
-                        || w.isResizedWhileNotDragResizing()) {
-                    if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || DEBUG_ORIENTATION || DEBUG_RESIZE) {
-                        Slog.v(TAG_WM, "Orientation or resize start waiting for draw"
-                                + ", mDrawState=DRAW_PENDING in " + w
-                                + ", surfaceController " + winAnimator.mSurfaceController);
-                    }
-                    winAnimator.mDrawState = DRAW_PENDING;
-                    if (w.mAppToken != null) {
-                        w.mAppToken.clearAllDrawn();
-                    }
-                }
-                if (!mResizingWindows.contains(w)) {
-                    if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG_WM,
-                            "Resizing window " + w);
-                    mResizingWindows.add(w);
-                }
-            } else if (w.mOrientationChanging) {
-                if (w.isDrawnLw()) {
-                    if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
-                            "Orientation not waiting for draw in "
-                            + w + ", surfaceController " + winAnimator.mSurfaceController);
-                    w.mOrientationChanging = false;
-                    w.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
-                            - mDisplayFreezeTime);
-                }
-            }
-        }
-    }
-
     void checkDrawnWindowsLocked() {
         if (mWaitingForDrawn.isEmpty() || mWaitingForDrawnCallback == null) {
             return;
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index ee2da13..206ec78 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -87,6 +87,7 @@
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
@@ -131,6 +132,7 @@
 import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_TIMEOUT;
 import static com.android.server.wm.WindowManagerService.localLOGV;
 import static com.android.server.wm.WindowStateAnimator.COMMIT_DRAW_PENDING;
+import static com.android.server.wm.WindowStateAnimator.DRAW_PENDING;
 import static com.android.server.wm.WindowStateAnimator.HAS_DRAWN;
 import static com.android.server.wm.WindowStateAnimator.READY_TO_SHOW;
 
@@ -1081,6 +1083,112 @@
                 || mOutsetsChanged || mFrameSizeChanged;
     }
 
+    /**
+     * Adds the window to the resizing list if any of the parameters we use to track the window
+     * dimensions or insets have changed.
+     */
+    void updateResizingWindowIfNeeded() {
+        final WindowStateAnimator winAnimator = mWinAnimator;
+        if (!mHasSurface || mService.mLayoutSeq != mLayoutSeq || isGoneForLayoutLw()) {
+            return;
+        }
+
+        final Task task = getTask();
+        // In the case of stack bound animations, the window frames will update (unlike other
+        // animations which just modify various transformation properties). We don't want to
+        // notify the client of frame changes in this case. Not only is it a lot of churn, but
+        // the frame may not correspond to the surface size or the onscreen area at various
+        // phases in the animation, and the client will become sad and confused.
+        if (task != null && task.mStack.getBoundsAnimating()) {
+            return;
+        }
+
+        setReportResizeHints();
+        boolean configChanged = isConfigChanged();
+        if (DEBUG_CONFIGURATION && configChanged) {
+            Slog.v(TAG_WM, "Win " + this + " config changed: " + getConfiguration());
+        }
+
+        final boolean dragResizingChanged = isDragResizeChanged()
+                && !isDragResizingChangeReported();
+
+        if (localLOGV) Slog.v(TAG_WM, "Resizing " + this + ": configChanged=" + configChanged
+                + " dragResizingChanged=" + dragResizingChanged + " last=" + mLastFrame
+                + " frame=" + mFrame);
+
+        // We update mLastFrame always rather than in the conditional with the last inset
+        // variables, because mFrameSizeChanged only tracks the width and height changing.
+        mLastFrame.set(mFrame);
+
+        if (mContentInsetsChanged
+                || mVisibleInsetsChanged
+                || winAnimator.mSurfaceResized
+                || mOutsetsChanged
+                || mFrameSizeChanged
+                || configChanged
+                || dragResizingChanged
+                || !isResizedWhileNotDragResizingReported()) {
+            if (DEBUG_RESIZE || DEBUG_ORIENTATION) {
+                Slog.v(TAG_WM, "Resize reasons for w=" + this + ": "
+                        + " contentInsetsChanged=" + mContentInsetsChanged
+                        + " " + mContentInsets.toShortString()
+                        + " visibleInsetsChanged=" + mVisibleInsetsChanged
+                        + " " + mVisibleInsets.toShortString()
+                        + " stableInsetsChanged=" + mStableInsetsChanged
+                        + " " + mStableInsets.toShortString()
+                        + " outsetsChanged=" + mOutsetsChanged
+                        + " " + mOutsets.toShortString()
+                        + " surfaceResized=" + winAnimator.mSurfaceResized
+                        + " configChanged=" + configChanged
+                        + " dragResizingChanged=" + dragResizingChanged
+                        + " resizedWhileNotDragResizingReported="
+                        + isResizedWhileNotDragResizingReported());
+            }
+
+            // If it's a dead window left on screen, and the configuration changed, there is nothing
+            // we can do about it. Remove the window now.
+            if (mAppToken != null && mAppDied) {
+                mAppToken.removeDeadWindows();
+                return;
+            }
+
+            mLastOverscanInsets.set(mOverscanInsets);
+            mLastContentInsets.set(mContentInsets);
+            mLastVisibleInsets.set(mVisibleInsets);
+            mLastStableInsets.set(mStableInsets);
+            mLastOutsets.set(mOutsets);
+            mService.makeWindowFreezingScreenIfNeededLocked(this);
+
+            // If the orientation is changing, or we're starting or ending a drag resizing action,
+            // then we need to hold off on unfreezing the display until this window has been
+            // redrawn; to do that, we need to go through the process of getting informed by the
+            // application when it has finished drawing.
+            if (mOrientationChanging || dragResizingChanged || isResizedWhileNotDragResizing()) {
+                if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || DEBUG_ORIENTATION || DEBUG_RESIZE) {
+                    Slog.v(TAG_WM, "Orientation or resize start waiting for draw"
+                            + ", mDrawState=DRAW_PENDING in " + this
+                            + ", surfaceController " + winAnimator.mSurfaceController);
+                }
+                winAnimator.mDrawState = DRAW_PENDING;
+                if (mAppToken != null) {
+                    mAppToken.clearAllDrawn();
+                }
+            }
+            if (!mService.mResizingWindows.contains(this)) {
+                if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG_WM, "Resizing window " + this);
+                mService.mResizingWindows.add(this);
+            }
+        } else if (mOrientationChanging) {
+            if (isDrawnLw()) {
+                if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Orientation not waiting for draw in "
+                        + this + ", surfaceController " + winAnimator.mSurfaceController);
+                mOrientationChanging = false;
+                mLastFreezeDuration = (int)(SystemClock.elapsedRealtime()
+                        - mService.mDisplayFreezeTime);
+            }
+        }
+    }
+
     public DisplayContent getDisplayContent() {
         if (mAppToken == null || mNotOnAppsDisplay) {
             return mDisplayContent;
@@ -1426,7 +1534,7 @@
      * Return true if the window is opaque and fully drawn.  This indicates
      * it may obscure windows behind it.
      */
-    boolean isOpaqueDrawn() {
+    private boolean isOpaqueDrawn() {
         // When there is keyguard, wallpaper could be placed over the secure app
         // window but invisible. We need to check wallpaper visibility explicitly
         // to determine if it's occluding apps.
@@ -1557,10 +1665,49 @@
     }
 
     /**
+     * If the window has moved due to its containing content frame changing, then notify the
+     * listeners and optionally animate it. Simply checking a change of position is not enough,
+     * because being move due to dock divider is not a trigger for animation.
+     */
+    void handleWindowMovedIfNeeded() {
+        if (!hasMoved()) {
+            return;
+        }
+
+        // Frame has moved, containing content frame has also moved, and we're not currently
+        // animating... let's do something.
+        final int left = mFrame.left;
+        final int top = mFrame.top;
+        final Task task = getTask();
+        final boolean adjustedForMinimizedDockOrIme = task != null
+                && (task.mStack.isAdjustedForMinimizedDockedStack()
+                || task.mStack.isAdjustedForIme());
+        if (mService.okToDisplay()
+                && (mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
+                && !isDragResizing() && !adjustedForMinimizedDockOrIme
+                && (task == null || getTask().mStack.hasMovementAnimations())
+                && !mWinAnimator.mLastHidden) {
+            mWinAnimator.setMoveAnimation(left, top);
+        }
+
+        //TODO (multidisplay): Accessibility supported only for the default display.
+        if (mService.mAccessibilityController != null
+                && getDisplayContent().getDisplayId() == Display.DEFAULT_DISPLAY) {
+            mService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
+        }
+
+        try {
+            mClient.moved(left, top);
+        } catch (RemoteException e) {
+        }
+        mMovedByResize = false;
+    }
+
+    /**
      * Return whether this window has moved. (Only makes
      * sense to call from performLayoutAndPlaceSurfacesLockedInner().)
      */
-    boolean hasMoved() {
+    private boolean hasMoved() {
         return mHasSurface && (mContentChanged || mMovedByResize)
                 && !mAnimatingExit
                 && (mFrame.top != mLastFrame.top || mFrame.left != mLastFrame.left)