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
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 756a3df..41a6ae7 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;
@@ -160,6 +159,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;
@@ -1454,8 +1454,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);
@@ -1522,7 +1523,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));
@@ -1547,11 +1548,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 1953ad7..13e8bc5 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 758b6e7..fdd8aab 100644
--- a/services/java/com/android/server/wm/WindowAnimator.java
+++ b/services/java/com/android/server/wm/WindowAnimator.java
@@ -38,7 +38,6 @@
ArrayList<WindowStateAnimator> mWinAnimators = new ArrayList<WindowStateAnimator>();
boolean mAnimating;
- boolean mTokenMayBeDrawn;
boolean mForceHiding;
WindowState mWindowAnimationBackground;
int mWindowAnimationBackgroundColor;
@@ -57,7 +56,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;
@@ -194,7 +193,7 @@
}
private void updateWindowsAndWallpaperLocked() {
- ++mTransactionSequence;
+ ++mAnimTransactionSequence;
ArrayList<WindowStateAnimator> unForceHiding = null;
boolean wallpaperInUnForceHiding = false;
@@ -332,59 +331,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);
- 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 @@
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 @@
}
private void performAnimationsLocked() {
- mTokenMayBeDrawn = false;
mForceHiding = false;
mDetachedWallpaper = null;
mWindowAnimationBackground = null;
@@ -465,9 +419,7 @@
mPendingActions |= WALLPAPER_ACTION_PENDING;
}
- if (mTokenMayBeDrawn) {
- testTokenMayBeDrawnLocked();
- }
+ testTokenMayBeDrawnLocked();
}
synchronized void animate() {
@@ -584,18 +536,23 @@
}
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 73bfe8e..3f19f17 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.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 @@
}
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 @@
@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 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 @@
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 @@
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 @@
// 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 @@
// 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 @@
}
}
+ 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 @@
// 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 @@
}
}
+ 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 @@
mInnerFields.mHoldScreen = null;
mInnerFields.mScreenBrightness = -1;
mInnerFields.mButtonBrightness = -1;
+ mTransactionSequence++;
if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
@@ -8560,6 +8602,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);
@@ -8616,6 +8659,53 @@
}
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 @@
updateResizingWindows(w);
}
+ if (updateAllDrawn) {
+ updateAllDrawnLocked();
+ }
+
if (focusDisplayed) {
mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
}
@@ -9753,7 +9847,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);
@@ -9814,6 +9909,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 109161a..03e52fe 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -120,6 +120,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? */
@@ -399,10 +409,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;
}
@@ -411,11 +430,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;
@@ -1214,7 +1239,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();
@@ -1223,12 +1249,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="
@@ -1237,7 +1258,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();
@@ -1425,7 +1463,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);