From 357d99c61d1c97199ca421408b3e26566e879f2a Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Wed, 20 Jun 2012 18:37:16 -0700 Subject: [PATCH] DO NOT MERGE Fix issue #6697105: App launching sometimes has random pauses 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/impl/PhoneWindowManager.java | 19 +-- .../android/server/wm/AppWindowAnimator.java | 4 + .../com/android/server/wm/AppWindowToken.java | 10 +- .../com/android/server/wm/WindowAnimator.java | 151 +++++++----------- .../server/wm/WindowManagerService.java | 111 ++++++++++++- .../server/wm/WindowStateAnimator.java | 59 +++++-- 6 files changed, 229 insertions(+), 125 deletions(-) diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index 756a3df770283..41a6ae7855369 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.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); diff --git a/services/java/com/android/server/wm/AppWindowAnimator.java b/services/java/com/android/server/wm/AppWindowAnimator.java index 1953ad77823c2..13e8bc5f1e255 100644 --- a/services/java/com/android/server/wm/AppWindowAnimator.java +++ b/services/java/com/android/server/wm/AppWindowAnimator.java @@ -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; diff --git a/services/java/com/android/server/wm/AppWindowToken.java b/services/java/com/android/server/wm/AppWindowToken.java index bf351540d1057..6ecbb8e33e529 100644 --- a/services/java/com/android/server/wm/AppWindowToken.java +++ b/services/java/com/android/server/wm/AppWindowToken.java @@ -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); diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java index 758b6e7431976..fdd8aaba97d51 100644 --- a/services/java/com/android/server/wm/WindowAnimator.java +++ b/services/java/com/android/server/wm/WindowAnimator.java @@ -38,7 +38,6 @@ public class WindowAnimator { ArrayList mWinAnimators = new ArrayList(); 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 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 (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); - 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) { @@ -414,39 +376,32 @@ public class WindowAnimator { final int NT = appTokens.size(); for (int i=0; i 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 "); + } } } diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index 73bfe8ec87741..3f19f17b13bbf 100755 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -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 appTokens = mAnimatingAppTokens; + final int NT = appTokens.size(); + for (int i=0; i 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); } } diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java index 109161ac9fc10..03e52fe6e20ab 100644 --- a/services/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/java/com/android/server/wm/WindowStateAnimator.java @@ -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);