Merge CL 202423/3 App launching has random pauses.

Change-Id: Iba5616182c02e51f4d9063d0a01b30b9f558549a
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 4206a97..ac74597 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -65,7 +65,6 @@
 import com.android.internal.widget.PointerLocationView;
 
 import android.service.dreams.IDreamManager;
-import android.speech.RecognizerIntent;
 import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.Log;
@@ -161,6 +160,7 @@
     static final boolean localLOGV = false;
     static final boolean DEBUG_LAYOUT = false;
     static final boolean DEBUG_INPUT = false;
+    static final boolean DEBUG_STARTING_WINDOW = false;
     static final boolean SHOW_STARTING_ANIMATIONS = true;
     static final boolean SHOW_PROCESSES_ON_ALT_MENU = false;
 
@@ -1479,8 +1479,9 @@
 
         try {
             Context context = mContext;
-            //Log.i(TAG, "addStartingWindow " + packageName + ": nonLocalizedLabel="
-            //        + nonLocalizedLabel + " theme=" + Integer.toHexString(theme));
+            if (DEBUG_STARTING_WINDOW) Slog.d(TAG, "addStartingWindow " + packageName
+                    + ": nonLocalizedLabel=" + nonLocalizedLabel + " theme="
+                    + Integer.toHexString(theme));
             if (theme != context.getThemeResId() || labelRes != 0) {
                 try {
                     context = context.createPackageContext(packageName, 0);
@@ -1547,7 +1548,7 @@
                 return null;
             }
 
-            if (localLOGV) Log.v(
+            if (DEBUG_STARTING_WINDOW) Slog.d(
                 TAG, "Adding starting window for " + packageName
                 + " / " + appToken + ": "
                 + (view.getParent() != null ? view : null));
@@ -1572,11 +1573,11 @@
 
     /** {@inheritDoc} */
     public void removeStartingWindow(IBinder appToken, View window) {
-        // RuntimeException e = new RuntimeException();
-        // Log.i(TAG, "remove " + appToken + " " + window, e);
-
-        if (localLOGV) Log.v(
-            TAG, "Removing starting window for " + appToken + ": " + window);
+        if (DEBUG_STARTING_WINDOW) {
+            RuntimeException e = new RuntimeException("here");
+            e.fillInStackTrace();
+            Log.v(TAG, "Removing starting window for " + appToken + ": " + window, e);
+        }
 
         if (window != null) {
             WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
diff --git a/services/java/com/android/server/wm/AppWindowAnimator.java b/services/java/com/android/server/wm/AppWindowAnimator.java
index a06e224..16461ab 100644
--- a/services/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/java/com/android/server/wm/AppWindowAnimator.java
@@ -35,6 +35,10 @@
     // AppWindowToken animations.
     int animLayerAdjustment;
 
+    // Propagated from AppWindowToken.allDrawn, to determine when
+    // the state changes.
+    boolean allDrawn;
+
     // Special surface for thumbnail animation.
     Surface thumbnail;
     int thumbnailTransactionSeq;
diff --git a/services/java/com/android/server/wm/AppWindowToken.java b/services/java/com/android/server/wm/AppWindowToken.java
index bf35154..6ecbb8e 100644
--- a/services/java/com/android/server/wm/AppWindowToken.java
+++ b/services/java/com/android/server/wm/AppWindowToken.java
@@ -241,12 +241,18 @@
             pw.print(prefix); pw.print("paused="); pw.println(paused);
         }
         if (numInterestingWindows != 0 || numDrawnWindows != 0
-                || inPendingTransaction || allDrawn) {
+                || allDrawn || mAppAnimator.allDrawn) {
             pw.print(prefix); pw.print("numInterestingWindows=");
                     pw.print(numInterestingWindows);
                     pw.print(" numDrawnWindows="); pw.print(numDrawnWindows);
                     pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
-                    pw.print(" allDrawn="); pw.println(allDrawn);
+                    pw.print(" allDrawn="); pw.print(allDrawn);
+                    pw.print(" (animator="); pw.print(mAppAnimator.allDrawn);
+                    pw.println(")");
+        }
+        if (inPendingTransaction) {
+            pw.print(prefix); pw.print("inPendingTransaction=");
+                    pw.println(inPendingTransaction);
         }
         if (startingData != null || removed || firstWindowDrawn) {
             pw.print(prefix); pw.print("startingData="); pw.print(startingData);
diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java
index 82d2e6a..528b374 100644
--- a/services/java/com/android/server/wm/WindowAnimator.java
+++ b/services/java/com/android/server/wm/WindowAnimator.java
@@ -17,7 +17,6 @@
 import android.util.Slog;
 import android.view.Choreographer;
 import android.view.Surface;
-import android.view.WindowManager;
 import android.view.WindowManagerPolicy;
 import android.view.animation.Animation;
 
@@ -46,7 +45,6 @@
     /** Variables only intended to be valid within each pass through animate(). Does not contain
      * persistent state. */
     private class InnerLoopParams {
-        boolean mTokenMayBeDrawn;
         boolean mForceHiding;
     }
     InnerLoopParams mInner = new InnerLoopParams();
@@ -78,7 +76,7 @@
 
     /** Skip repeated AppWindowTokens initialization. Note that AppWindowsToken's version of this
      * is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */
-    private int mTransactionSequence;
+    private int mAnimTransactionSequence;
 
     /** The one and only screen rotation if one is happening */
     ScreenRotationAnimation mScreenRotationAnimation = null;
@@ -218,7 +216,7 @@
     }
 
     private void updateWindowsAndWallpaperLocked() {
-        ++mTransactionSequence;
+        ++mAnimTransactionSequence;
 
         ArrayList<WindowStateAnimator> unForceHiding = null;
         boolean wallpaperInUnForceHiding = false;
@@ -358,59 +356,22 @@
             }
 
             final AppWindowToken atoken = win.mAppToken;
-            if (atoken != null && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) {
-                if (atoken.lastTransactionSequence != mTransactionSequence) {
-                    atoken.lastTransactionSequence = mTransactionSequence;
-                    atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
-                    atoken.startingDisplayed = false;
-                }
-                if ((win.isOnScreen() || winAnimator.mAttrType
-                        == WindowManager.LayoutParams.TYPE_BASE_APPLICATION)
-                        && !win.mExiting && !win.mDestroying) {
-                    if (WindowManagerService.DEBUG_VISIBILITY ||
-                            WindowManagerService.DEBUG_ORIENTATION) {
-                        Slog.v(TAG, "Eval win " + win + ": isDrawn=" + win.isDrawnLw()
-                                + ", isAnimating=" + winAnimator.isAnimating());
-                        if (!win.isDrawnLw()) {
-                            Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurface
-                                    + " pv=" + win.mPolicyVisibility
-                                    + " mDrawState=" + winAnimator.mDrawState
-                                    + " ah=" + win.mAttachedHidden
-                                    + " th=" + atoken.hiddenRequested
-                                    + " a=" + winAnimator.mAnimating);
+            if (winAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW) {
+                if (atoken == null || atoken.allDrawn) {
+                    if (winAnimator.performShowLocked()) {
+                        mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
+                        if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
+                            mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 5",
+                                mPendingLayoutChanges);
                         }
                     }
-                    if (win != atoken.startingWindow) {
-                        if (!atoken.mAppAnimator.freezingScreen || !win.mAppFreezing) {
-                            atoken.numInterestingWindows++;
-                            if (win.isDrawnLw()) {
-                                atoken.numDrawnWindows++;
-                                if (WindowManagerService.DEBUG_VISIBILITY ||
-                                        WindowManagerService.DEBUG_ORIENTATION) Slog.v(TAG,
-                                        "tokenMayBeDrawn: " + atoken
-                                        + " freezingScreen=" + atoken.mAppAnimator.freezingScreen
-                                        + " mAppFreezing=" + win.mAppFreezing);
-                                mInner.mTokenMayBeDrawn = true;
-                            }
-                        }
-                    } else if (win.isDrawnLw()) {
-                        atoken.startingDisplayed = true;
-                    }
-                }
-            } else if (winAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW) {
-                if (winAnimator.performShowLocked()) {
-                    mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
-                    if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
-                        mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 5",
-                            mPendingLayoutChanges);
-                    }
                 }
             }
             final AppWindowAnimator appAnimator =
                     atoken == null ? null : atoken.mAppAnimator;
             if (appAnimator != null && appAnimator.thumbnail != null) {
-                if (appAnimator.thumbnailTransactionSeq != mTransactionSequence) {
-                    appAnimator.thumbnailTransactionSeq = mTransactionSequence;
+                if (appAnimator.thumbnailTransactionSeq != mAnimTransactionSequence) {
+                    appAnimator.thumbnailTransactionSeq = mAnimTransactionSequence;
                     appAnimator.thumbnailLayer = 0;
                 }
                 if (appAnimator.thumbnailLayer < winAnimator.mAnimLayer) {
@@ -476,39 +437,32 @@
         final int NT = appTokens.size();
         for (int i=0; i<NT; i++) {
             AppWindowToken wtoken = appTokens.get(i);
-            if (wtoken.mAppAnimator.freezingScreen) {
-                int numInteresting = wtoken.numInterestingWindows;
-                if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
-                    if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
-                            "allDrawn: " + wtoken
-                            + " interesting=" + numInteresting
-                            + " drawn=" + wtoken.numDrawnWindows);
-                    wtoken.mAppAnimator.showAllWindowsLocked();
-                    mService.unsetAppFreezingScreenLocked(wtoken, false, true);
-                    if (WindowManagerService.DEBUG_ORIENTATION) Slog.i(TAG,
-                            "Setting mOrientationChangeComplete=true because wtoken "
-                            + wtoken + " numInteresting=" + numInteresting
-                            + " numDrawn=" + wtoken.numDrawnWindows);
-                    // This will set mOrientationChangeComplete and cause a pass through layout.
-                    mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
-                }
-            } else if (!wtoken.allDrawn) {
-                int numInteresting = wtoken.numInterestingWindows;
-                if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
-                    if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
-                            "allDrawn: " + wtoken
-                            + " interesting=" + numInteresting
-                            + " drawn=" + wtoken.numDrawnWindows);
-                    wtoken.allDrawn = true;
-                    mPendingLayoutChanges |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
-                    if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
-                        mService.debugLayoutRepeats("testTokenMayBeDrawnLocked",
-                            mPendingLayoutChanges);
-                    }
+            final boolean allDrawn = wtoken.allDrawn;
+            if (allDrawn != wtoken.mAppAnimator.allDrawn) {
+                wtoken.mAppAnimator.allDrawn = allDrawn;
+                if (allDrawn) {
+                    // The token has now changed state to having all
+                    // windows shown...  what to do, what to do?
+                    if (wtoken.mAppAnimator.freezingScreen) {
+                        wtoken.mAppAnimator.showAllWindowsLocked();
+                        mService.unsetAppFreezingScreenLocked(wtoken, false, true);
+                        if (WindowManagerService.DEBUG_ORIENTATION) Slog.i(TAG,
+                                "Setting mOrientationChangeComplete=true because wtoken "
+                                + wtoken + " numInteresting=" + wtoken.numInterestingWindows
+                                + " numDrawn=" + wtoken.numDrawnWindows);
+                        // This will set mOrientationChangeComplete and cause a pass through layout.
+                        mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+                    } else {
+                        mPendingLayoutChanges |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
+                        if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
+                            mService.debugLayoutRepeats("testTokenMayBeDrawnLocked",
+                                mPendingLayoutChanges);
+                        }
 
-                    // We can now show all of the drawn windows!
-                    if (!mService.mOpeningApps.contains(wtoken)) {
-                        mAnimating |= wtoken.mAppAnimator.showAllWindowsLocked();
+                        // We can now show all of the drawn windows!
+                        if (!mService.mOpeningApps.contains(wtoken)) {
+                            mAnimating |= wtoken.mAppAnimator.showAllWindowsLocked();
+                        }
                     }
                 }
             }
@@ -516,7 +470,6 @@
     }
 
     private void performAnimationsLocked() {
-        mInner.mTokenMayBeDrawn = false;
         mInner.mForceHiding = false;
 
         updateWindowsAndWallpaperLocked();
@@ -524,9 +477,7 @@
             mPendingActions |= WALLPAPER_ACTION_PENDING;
         }
 
-        if (mInner.mTokenMayBeDrawn) {
-            testTokenMayBeDrawnLocked();
-        }
+        testTokenMayBeDrawnLocked();
     }
 
     // TODO(cmautner): Change the following comment when no longer locked on mWindowMap */
@@ -654,21 +605,23 @@
     }
 
     public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
-        if (mWindowDetachedWallpaper != null) {
-            pw.print("  mWindowDetachedWallpaper="); pw.println(mWindowDetachedWallpaper);
-        }
-        if (mUniverseBackground != null) {
-            pw.print("  mUniverseBackground="); pw.println(mUniverseBackground);
-        }
-        if (mWindowAnimationBackgroundSurface != null) {
-            pw.println("  mWindowAnimationBackgroundSurface:");
-            mWindowAnimationBackgroundSurface.printTo("    ", pw);
-        }
-        if (mDimAnimator != null) {
-            pw.println("  mDimAnimator:");
-            mDimAnimator.printTo("    ", pw);
-        } else {
-            pw.println( "  no DimAnimator ");
+        if (dumpAll) {
+            if (mWindowDetachedWallpaper != null) {
+                pw.print(prefix); pw.print("mWindowDetachedWallpaper=");
+                        pw.println(mWindowDetachedWallpaper);
+            }
+            pw.print(prefix); pw.print("mAnimTransactionSequence=");
+                    pw.println(mAnimTransactionSequence);
+            if (mWindowAnimationBackgroundSurface != null) {
+                pw.print(prefix); pw.print("mWindowAnimationBackgroundSurface:");
+                        mWindowAnimationBackgroundSurface.printTo(prefix + "  ", pw);
+            }
+            if (mDimAnimator != null) {
+                pw.print(prefix); pw.print("mDimAnimator:");
+                mDimAnimator.printTo(prefix + "  ", pw);
+            } else {
+                pw.print(prefix); pw.print("no DimAnimator ");
+            }
         }
     }
 
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 4edc9dd..1dd7751 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -98,6 +98,7 @@
 import android.util.EventLog;
 import android.util.FloatMath;
 import android.util.Log;
+import android.util.LogPrinter;
 import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseIntArray;
@@ -660,6 +661,10 @@
     /** The lowest wallpaper target with a detached wallpaper animation on it. */
     WindowState mWindowDetachedWallpaper = null;
 
+    /** Skip repeated AppWindowTokens initialization. Note that AppWindowsToken's version of this
+     * is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */
+    private int mTransactionSequence;
+
     /** Only do a maximum of 6 repeated layouts. After that quit */
     private int mLayoutRepeatCount;
 
@@ -793,6 +798,8 @@
         @Override
         public void run() {
             Looper.prepare();
+            //Looper.myLooper().setMessageLogging(new LogPrinter(
+            //        android.util.Log.DEBUG, TAG, android.util.Log.LOG_ID_SYSTEM));
             WindowManagerService s = new WindowManagerService(mContext, mPM,
                     mHaveInputMethods, mAllowBootMessages, mOnlyCore);
             android.os.Process.setThreadPriority(
@@ -3604,7 +3611,7 @@
     @Override
     public void setAppGroupId(IBinder token, int groupId) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
-                "setAppStartingIcon()")) {
+                "setAppGroupId()")) {
             throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
 
@@ -4027,7 +4034,7 @@
             CharSequence nonLocalizedLabel, int labelRes, int icon,
             int windowFlags, IBinder transferFrom, boolean createIfNeeded) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
-                "setAppStartingIcon()")) {
+                "setAppStartingWindow()")) {
             throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
         }
 
@@ -4083,12 +4090,13 @@
                         startingWindow.mToken = wtoken;
                         startingWindow.mRootToken = wtoken;
                         startingWindow.mAppToken = wtoken;
-                        if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG,
-                                "Removing starting window: " + startingWindow);
+                        if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) {
+                            Slog.v(TAG, "Removing starting window: " + startingWindow);
+                        }
                         mWindows.remove(startingWindow);
                         mWindowsChanged = true;
-                        if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing starting " + startingWindow
-                                + " from " + ttoken);
+                        if (DEBUG_ADD_REMOVE) Slog.v(TAG,
+                                "Removing starting " + startingWindow + " from " + ttoken);
                         ttoken.windows.remove(startingWindow);
                         ttoken.allAppWindows.remove(startingWindow);
                         addWindowToListInOrderLocked(startingWindow, true);
@@ -4175,6 +4183,8 @@
             // show a starting window -- the current effect (a full-screen
             // opaque starting window that fades away to the real contents
             // when it is ready) does not work for this.
+            if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Checking theme of starting window: 0x"
+                    + Integer.toHexString(theme));
             if (theme != 0) {
                 AttributeCache.Entry ent = AttributeCache.instance().get(pkg, theme,
                         com.android.internal.R.styleable.Window);
@@ -4183,6 +4193,15 @@
                     // pretend like we didn't see that.
                     return;
                 }
+                if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Translucent="
+                        + ent.array.getBoolean(
+                                com.android.internal.R.styleable.Window_windowIsTranslucent, false)
+                        + " Floating="
+                        + ent.array.getBoolean(
+                                com.android.internal.R.styleable.Window_windowIsFloating, false)
+                        + " ShowWallpaper="
+                        + ent.array.getBoolean(
+                                com.android.internal.R.styleable.Window_windowShowWallpaper, false));
                 if (ent.array.getBoolean(
                         com.android.internal.R.styleable.Window_windowIsTranslucent, false)) {
                     return;
@@ -4206,6 +4225,7 @@
                 }
             }
 
+            if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Creating StartingData");
             mStartingIconInTransition = true;
             wtoken.startingData = new StartingData(pkg, theme, compatInfo, nonLocalizedLabel,
                     labelRes, icon, windowFlags);
@@ -4213,6 +4233,7 @@
             // Note: we really want to do sendMessageAtFrontOfQueue() because we
             // want to process the message ASAP, before any other queued
             // messages.
+            if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Enqueueing ADD_STARTING");
             mH.sendMessageAtFrontOfQueue(m);
         }
     }
@@ -8513,6 +8534,26 @@
         }
     }
 
+    private void updateAllDrawnLocked() {
+        // See if any windows have been drawn, so they (and others
+        // associated with them) can now be shown.
+        final ArrayList<AppWindowToken> appTokens = mAnimatingAppTokens;
+        final int NT = appTokens.size();
+        for (int i=0; i<NT; i++) {
+            AppWindowToken wtoken = appTokens.get(i);
+            if (!wtoken.allDrawn) {
+                int numInteresting = wtoken.numInterestingWindows;
+                if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
+                    if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
+                            "allDrawn: " + wtoken
+                            + " interesting=" + numInteresting
+                            + " drawn=" + wtoken.numDrawnWindows);
+                    wtoken.allDrawn = true;
+                }
+            }
+        }
+    }
+
     // "Something has changed!  Let's make it correct now."
     private final void performLayoutAndPlaceSurfacesLockedInner(
             boolean recoveringMemory) {
@@ -8552,6 +8593,7 @@
         mInnerFields.mHoldScreen = null;
         mInnerFields.mScreenBrightness = -1;
         mInnerFields.mButtonBrightness = -1;
+        mTransactionSequence++;
 
         if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
                 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
@@ -8629,6 +8671,7 @@
             mInnerFields.mSyswin = false;
 
             boolean focusDisplayed = false;
+            boolean updateAllDrawn = false;
             final int N = mWindows.size();
             for (i=N-1; i>=0; i--) {
                 WindowState w = mWindows.get(i);
@@ -8678,13 +8721,61 @@
                             mInnerFields.mWallpaperMayChange = true;
                             mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
                             if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
-                                debugLayoutRepeats("updateWindowsAndWallpaperLocked 1",
+                                debugLayoutRepeats("wallpaper and commitFinishDrawingLocked true",
                                     mPendingLayoutChanges);
                             }
                         }
                     }
 
                     winAnimator.setSurfaceBoundaries(recoveringMemory);
+
+                    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.mAppAnimator.freezingScreen)) {
+                        if (atoken.lastTransactionSequence != mTransactionSequence) {
+                            atoken.lastTransactionSequence = mTransactionSequence;
+                            atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
+                            atoken.startingDisplayed = false;
+                        }
+                        if ((w.isOnScreen() || winAnimator.mAttrType
+                                == WindowManager.LayoutParams.TYPE_BASE_APPLICATION)
+                                && !w.mExiting && !w.mDestroying) {
+                            if (WindowManagerService.DEBUG_VISIBILITY ||
+                                    WindowManagerService.DEBUG_ORIENTATION) {
+                                Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw()
+                                        + ", isAnimating=" + winAnimator.isAnimating());
+                                if (!w.isDrawnLw()) {
+                                    Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurface
+                                            + " pv=" + w.mPolicyVisibility
+                                            + " mDrawState=" + winAnimator.mDrawState
+                                            + " ah=" + w.mAttachedHidden
+                                            + " th=" + atoken.hiddenRequested
+                                            + " a=" + winAnimator.mAnimating);
+                                }
+                            }
+                            if (w != atoken.startingWindow) {
+                                if (!atoken.mAppAnimator.freezingScreen || !w.mAppFreezing) {
+                                    atoken.numInterestingWindows++;
+                                    if (w.isDrawnLw()) {
+                                        atoken.numDrawnWindows++;
+                                        if (WindowManagerService.DEBUG_VISIBILITY ||
+                                                WindowManagerService.DEBUG_ORIENTATION) Slog.v(TAG,
+                                                "tokenMayBeDrawn: " + atoken
+                                                + " freezingScreen=" + atoken.mAppAnimator.freezingScreen
+                                                + " mAppFreezing=" + w.mAppFreezing);
+                                        updateAllDrawn = true;
+                                    }
+                                }
+                            } else if (w.isDrawnLw()) {
+                                atoken.startingDisplayed = true;
+                            }
+                        }
+                    }
                 }
 
                 if (someoneLosingFocus && w == mCurrentFocus && w.isDisplayedLw()) {
@@ -8694,6 +8785,10 @@
                 updateResizingWindows(w);
             }
 
+            if (updateAllDrawn) {
+                updateAllDrawnLocked();
+            }
+
             if (focusDisplayed) {
                 mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
             }
@@ -9839,7 +9934,8 @@
             }
             pw.print("  mSystemBooted="); pw.print(mSystemBooted);
                     pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
-            pw.print("  mLayoutNeeded="); pw.println(mLayoutNeeded);
+            pw.print("  mLayoutNeeded="); pw.print(mLayoutNeeded);
+                    pw.print("mTransactionSequence="); pw.println(mTransactionSequence);
             pw.print("  mDisplayFrozen="); pw.print(mDisplayFrozen);
                     pw.print(" mWindowsFreezingScreen="); pw.print(mWindowsFreezingScreen);
                     pw.print(" mAppsFreezingScreen="); pw.print(mAppsFreezingScreen);
@@ -9900,6 +9996,8 @@
             }
             pw.print("  mStartingIconInTransition="); pw.print(mStartingIconInTransition);
                     pw.print(" mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
+            pw.println("  Window Animator:");
+            mAnimator.dump(pw, "    ", dumpAll);
         }
     }
 
diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java
index 3d0c6de..606558b 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -124,6 +124,16 @@
     static final int READY_TO_SHOW = 3;
     /** Set when the window has been shown in the screen the first time. */
     static final int HAS_DRAWN = 4;
+    static String drawStateToString(int state) {
+        switch (state) {
+            case NO_SURFACE: return "NO_SURFACE";
+            case DRAW_PENDING: return "DRAW_PENDING";
+            case COMMIT_DRAW_PENDING: return "COMMIT_DRAW_PENDING";
+            case READY_TO_SHOW: return "READY_TO_SHOW";
+            case HAS_DRAWN: return "HAS_DRAWN";
+            default: return Integer.toString(state);
+        }
+    }
     int mDrawState;
 
     /** Was this window last hidden? */
@@ -403,10 +413,19 @@
     }
 
     boolean finishDrawingLocked() {
+        if (DEBUG_STARTING_WINDOW &&
+                mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
+            Slog.v(TAG, "Finishing drawing window " + mWin + ": mDrawState="
+                    + drawStateToString(mDrawState));
+        }
         if (mDrawState == DRAW_PENDING) {
             if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
                 Slog.v(TAG, "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING " + this + " in "
                         + mSurface);
+            if (DEBUG_STARTING_WINDOW &&
+                    mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
+                Slog.v(TAG, "Draw state now committed in " + mWin);
+            }
             mDrawState = COMMIT_DRAW_PENDING;
             return true;
         }
@@ -415,11 +434,17 @@
 
     // This must be called while inside a transaction.
     boolean commitFinishDrawingLocked(long currentTime) {
+        if (DEBUG_STARTING_WINDOW &&
+                mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
+            Slog.i(TAG, "commitFinishDrawingLocked: " + mWin + " cur mDrawState="
+                    + drawStateToString(mDrawState));
+        }
         if (mDrawState != COMMIT_DRAW_PENDING) {
             return false;
         }
-        if (DEBUG_SURFACE_TRACE || DEBUG_ANIM)
+        if (DEBUG_SURFACE_TRACE || DEBUG_ANIM) {
             Slog.i(TAG, "commitFinishDrawingLocked: mDrawState=READY_TO_SHOW " + mSurface);
+        }
         mDrawState = READY_TO_SHOW;
         final boolean starting = mWin.mAttrs.type == TYPE_APPLICATION_STARTING;
         final AppWindowToken atoken = mWin.mAppToken;
@@ -1262,7 +1287,8 @@
 
     // This must be called while inside a transaction.
     boolean performShowLocked() {
-        if (DEBUG_VISIBILITY) {
+        if (DEBUG_VISIBILITY || (DEBUG_STARTING_WINDOW &&
+                mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING)) {
             RuntimeException e = null;
             if (!WindowManagerService.HIDE_STACK_CRAWLS) {
                 e = new RuntimeException();
@@ -1271,12 +1297,7 @@
             Slog.v(TAG, "performShow on " + this
                     + ": mDrawState=" + mDrawState + " readyForDisplay="
                     + mWin.isReadyForDisplayIgnoringKeyguard()
-                    + " starting=" + (mWin.mAttrs.type == TYPE_APPLICATION_STARTING), e);
-        }
-        if (mDrawState == READY_TO_SHOW && mWin.isReadyForDisplayIgnoringKeyguard()) {
-            if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
-                WindowManagerService.logSurface(mWin, "SHOW (performShowLocked)", null);
-            if (DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + this
+                    + " starting=" + (mWin.mAttrs.type == TYPE_APPLICATION_STARTING)
                     + " during animation: policyVis=" + mWin.mPolicyVisibility
                     + " attHidden=" + mWin.mAttachedHidden
                     + " tok.hiddenRequested="
@@ -1285,7 +1306,24 @@
                     + (mWin.mAppToken != null ? mWin.mAppToken.hidden : false)
                     + " animating=" + mAnimating
                     + " tok animating="
-                    + (mWin.mAppToken != null ? mWin.mAppToken.mAppAnimator.animating : false));
+                    + (mWin.mAppToken != null ? mWin.mAppToken.mAppAnimator.animating : false), e);
+        }
+        if (mDrawState == READY_TO_SHOW && mWin.isReadyForDisplayIgnoringKeyguard()) {
+            if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
+                WindowManagerService.logSurface(mWin, "SHOW (performShowLocked)", null);
+            if (DEBUG_VISIBILITY || (DEBUG_STARTING_WINDOW &&
+                    mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING)) {
+                Slog.v(TAG, "Showing " + this
+                        + " during animation: policyVis=" + mWin.mPolicyVisibility
+                        + " attHidden=" + mWin.mAttachedHidden
+                        + " tok.hiddenRequested="
+                        + (mWin.mAppToken != null ? mWin.mAppToken.hiddenRequested : false)
+                        + " tok.hidden="
+                        + (mWin.mAppToken != null ? mWin.mAppToken.hidden : false)
+                        + " animating=" + mAnimating
+                        + " tok animating="
+                        + (mWin.mAppToken != null ? mWin.mAppToken.mAppAnimator.animating : false));
+            }
 
             mService.enableScreenIfNeededLocked();
 
@@ -1473,7 +1511,8 @@
         if (mSurface != null) {
             if (dumpAll) {
                 pw.print(prefix); pw.print("mSurface="); pw.println(mSurface);
-                pw.print(prefix); pw.print("mDrawState="); pw.print(mDrawState);
+                pw.print(prefix); pw.print("mDrawState=");
+                pw.print(drawStateToString(mDrawState));
                 pw.print(" mLastHidden="); pw.println(mLastHidden);
             }
             pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);