OSDN Git Service

DO NOT MERGE Fix issue #6697105: App launching sometimes has random pauses
authorDianne Hackborn <hackbod@google.com>
Thu, 21 Jun 2012 01:37:16 +0000 (18:37 -0700)
committerDianne Hackborn <hackbod@google.com>
Fri, 22 Jun 2012 19:50:50 +0000 (12:50 -0700)
In the course of the window manager refactoring into a separate
layout state, we introduced a bad interaction between the two
sides of the world.  This resulting in multiple hops needed between
the two sides after an application has said it is finished drawing
its window, until the window/app transition is actually started.
Especially since these hops require going through the anim side
which is vsynced (so will delay its operation until the next frame),
this could introduce a notable delay until the window is first shown.

Fix this by re-arranging the code to make one straight path from
when a window reports it is shown to us starting the app transition
that is waiting for it.  This change also includes various improvements
to debugging code that was done while working on it.

Change-Id: I7883674052da1a58df89cd1d9b8d754843cdd3db

policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
services/java/com/android/server/wm/AppWindowAnimator.java
services/java/com/android/server/wm/AppWindowToken.java
services/java/com/android/server/wm/WindowAnimator.java
services/java/com/android/server/wm/WindowManagerService.java
services/java/com/android/server/wm/WindowStateAnimator.java

index 756a3df..41a6ae7 100755 (executable)
@@ -65,7 +65,6 @@ import com.android.internal.telephony.ITelephony;
 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;
@@ -160,6 +159,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
     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;
 
@@ -1454,8 +1454,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
 
         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);
@@ -1522,7 +1523,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                 return null;
             }
 
-            if (localLOGV) Log.v(
+            if (DEBUG_STARTING_WINDOW) Slog.d(
                 TAG, "Adding starting window for " + packageName
                 + " / " + appToken + ": "
                 + (view.getParent() != null ? view : null));
@@ -1547,11 +1548,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
 
     /** {@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);
index 1953ad7..13e8bc5 100644 (file)
@@ -35,6 +35,10 @@ public class AppWindowAnimator {
     // 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;
index bf35154..6ecbb8e 100644 (file)
@@ -241,12 +241,18 @@ class AppWindowToken extends WindowToken {
             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);
index 758b6e7..fdd8aab 100644 (file)
@@ -38,7 +38,6 @@ public class WindowAnimator {
     ArrayList<WindowStateAnimator> mWinAnimators = new ArrayList<WindowStateAnimator>();
 
     boolean mAnimating;
-    boolean mTokenMayBeDrawn;
     boolean mForceHiding;
     WindowState mWindowAnimationBackground;
     int mWindowAnimationBackgroundColor;
@@ -57,7 +56,7 @@ public class WindowAnimator {
 
     /** 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;
@@ -194,7 +193,7 @@ public class WindowAnimator {
     }
 
     private void updateWindowsAndWallpaperLocked() {
-        ++mTransactionSequence;
+        ++mAnimTransactionSequence;
 
         ArrayList<WindowStateAnimator> unForceHiding = null;
         boolean wallpaperInUnForceHiding = false;
@@ -332,59 +331,22 @@ public class WindowAnimator {
             }
 
             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 (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);
-                                mTokenMayBeDrawn = true;
-                            }
+            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);
                         }
-                    } 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) {
@@ -414,39 +376,32 @@ public class WindowAnimator {
         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();
+                        }
                     }
                 }
             }
@@ -454,7 +409,6 @@ public class WindowAnimator {
     }
 
     private void performAnimationsLocked() {
-        mTokenMayBeDrawn = false;
         mForceHiding = false;
         mDetachedWallpaper = null;
         mWindowAnimationBackground = null;
@@ -465,9 +419,7 @@ public class WindowAnimator {
             mPendingActions |= WALLPAPER_ACTION_PENDING;
         }
 
-        if (mTokenMayBeDrawn) {
-            testTokenMayBeDrawnLocked();
-        }
+        testTokenMayBeDrawnLocked();
     }
 
     synchronized void animate() {
@@ -584,18 +536,23 @@ public class WindowAnimator {
     }
 
     public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
-        if (mWindowDetachedWallpaper != null) {
-            pw.print("  mWindowDetachedWallpaper="); pw.println(mWindowDetachedWallpaper);
-        }
-        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 ");
+            }
         }
     }
 
index 73bfe8e..3f19f17 100755 (executable)
@@ -96,6 +96,7 @@ import android.util.DisplayMetrics;
 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;
@@ -642,6 +643,10 @@ public class WindowManagerService extends IWindowManager.Stub
     }
     LayoutFields mInnerFields = new LayoutFields();
 
+    /** 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;
 
@@ -794,6 +799,8 @@ public class WindowManagerService extends IWindowManager.Stub
         @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);
             android.os.Process.setThreadPriority(
@@ -3573,7 +3580,7 @@ public class WindowManagerService extends IWindowManager.Stub
 
     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");
         }
 
@@ -3996,7 +4003,7 @@ public class WindowManagerService extends IWindowManager.Stub
             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");
         }
 
@@ -4052,12 +4059,13 @@ public class WindowManagerService extends IWindowManager.Stub
                         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);
@@ -4144,6 +4152,8 @@ public class WindowManagerService extends IWindowManager.Stub
             // 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);
@@ -4152,6 +4162,15 @@ public class WindowManagerService extends IWindowManager.Stub
                     // 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;
@@ -4175,6 +4194,7 @@ public class WindowManagerService extends IWindowManager.Stub
                 }
             }
 
+            if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Creating StartingData");
             mStartingIconInTransition = true;
             wtoken.startingData = new StartingData(pkg, theme, compatInfo, nonLocalizedLabel,
                     labelRes, icon, windowFlags);
@@ -4182,6 +4202,7 @@ public class WindowManagerService extends IWindowManager.Stub
             // 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);
         }
     }
@@ -8444,6 +8465,26 @@ public class WindowManagerService extends IWindowManager.Stub
         }
     }
 
+    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) {
@@ -8483,6 +8524,7 @@ public class WindowManagerService extends IWindowManager.Stub
         mInnerFields.mHoldScreen = null;
         mInnerFields.mScreenBrightness = -1;
         mInnerFields.mButtonBrightness = -1;
+        mTransactionSequence++;
 
         if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
                 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
@@ -8560,6 +8602,7 @@ public class WindowManagerService extends IWindowManager.Stub
             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);
@@ -8616,6 +8659,53 @@ public class WindowManagerService extends IWindowManager.Stub
                     }
 
                     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()) {
@@ -8625,6 +8715,10 @@ public class WindowManagerService extends IWindowManager.Stub
                 updateResizingWindows(w);
             }
 
+            if (updateAllDrawn) {
+                updateAllDrawnLocked();
+            }
+
             if (focusDisplayed) {
                 mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
             }
@@ -9753,7 +9847,8 @@ public class WindowManagerService extends IWindowManager.Stub
             }
             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);
@@ -9814,6 +9909,8 @@ public class WindowManagerService extends IWindowManager.Stub
             }
             pw.print("  mStartingIconInTransition="); pw.print(mStartingIconInTransition);
                     pw.print(" mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
+            pw.println("  Window Animator:");
+            mAnimator.dump(pw, "    ", dumpAll);
         }
     }
 
index 109161a..03e52fe 100644 (file)
@@ -120,6 +120,16 @@ class WindowStateAnimator {
     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? */
@@ -399,10 +409,19 @@ class WindowStateAnimator {
     }
 
     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;
         }
@@ -411,11 +430,17 @@ class WindowStateAnimator {
 
     // 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;
@@ -1214,7 +1239,8 @@ class WindowStateAnimator {
 
     // 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();
@@ -1223,12 +1249,7 @@ class WindowStateAnimator {
             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="
@@ -1237,7 +1258,24 @@ class WindowStateAnimator {
                     + (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();
 
@@ -1425,7 +1463,8 @@ class WindowStateAnimator {
         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);