Skip to content

Commit 357d99c

Browse files
author
Dianne Hackborn
committed
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
1 parent 3cd4624 commit 357d99c

File tree

6 files changed

+229
-125
lines changed

6 files changed

+229
-125
lines changed

policy/src/com/android/internal/policy/impl/PhoneWindowManager.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@
6565
import com.android.internal.widget.PointerLocationView;
6666

6767
import android.service.dreams.IDreamManager;
68-
import android.speech.RecognizerIntent;
6968
import android.util.DisplayMetrics;
7069
import android.util.EventLog;
7170
import android.util.Log;
@@ -160,6 +159,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
160159
static final boolean localLOGV = false;
161160
static final boolean DEBUG_LAYOUT = false;
162161
static final boolean DEBUG_INPUT = false;
162+
static final boolean DEBUG_STARTING_WINDOW = false;
163163
static final boolean SHOW_STARTING_ANIMATIONS = true;
164164
static final boolean SHOW_PROCESSES_ON_ALT_MENU = false;
165165

@@ -1454,8 +1454,9 @@ public View addStartingWindow(IBinder appToken, String packageName, int theme,
14541454

14551455
try {
14561456
Context context = mContext;
1457-
//Log.i(TAG, "addStartingWindow " + packageName + ": nonLocalizedLabel="
1458-
// + nonLocalizedLabel + " theme=" + Integer.toHexString(theme));
1457+
if (DEBUG_STARTING_WINDOW) Slog.d(TAG, "addStartingWindow " + packageName
1458+
+ ": nonLocalizedLabel=" + nonLocalizedLabel + " theme="
1459+
+ Integer.toHexString(theme));
14591460
if (theme != context.getThemeResId() || labelRes != 0) {
14601461
try {
14611462
context = context.createPackageContext(packageName, 0);
@@ -1522,7 +1523,7 @@ public View addStartingWindow(IBinder appToken, String packageName, int theme,
15221523
return null;
15231524
}
15241525

1525-
if (localLOGV) Log.v(
1526+
if (DEBUG_STARTING_WINDOW) Slog.d(
15261527
TAG, "Adding starting window for " + packageName
15271528
+ " / " + appToken + ": "
15281529
+ (view.getParent() != null ? view : null));
@@ -1547,11 +1548,11 @@ public View addStartingWindow(IBinder appToken, String packageName, int theme,
15471548

15481549
/** {@inheritDoc} */
15491550
public void removeStartingWindow(IBinder appToken, View window) {
1550-
// RuntimeException e = new RuntimeException();
1551-
// Log.i(TAG, "remove " + appToken + " " + window, e);
1552-
1553-
if (localLOGV) Log.v(
1554-
TAG, "Removing starting window for " + appToken + ": " + window);
1551+
if (DEBUG_STARTING_WINDOW) {
1552+
RuntimeException e = new RuntimeException("here");
1553+
e.fillInStackTrace();
1554+
Log.v(TAG, "Removing starting window for " + appToken + ": " + window, e);
1555+
}
15551556

15561557
if (window != null) {
15571558
WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);

services/java/com/android/server/wm/AppWindowAnimator.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ public class AppWindowAnimator {
3535
// AppWindowToken animations.
3636
int animLayerAdjustment;
3737

38+
// Propagated from AppWindowToken.allDrawn, to determine when
39+
// the state changes.
40+
boolean allDrawn;
41+
3842
// Special surface for thumbnail animation.
3943
Surface thumbnail;
4044
int thumbnailTransactionSeq;

services/java/com/android/server/wm/AppWindowToken.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,12 +241,18 @@ void dump(PrintWriter pw, String prefix) {
241241
pw.print(prefix); pw.print("paused="); pw.println(paused);
242242
}
243243
if (numInterestingWindows != 0 || numDrawnWindows != 0
244-
|| inPendingTransaction || allDrawn) {
244+
|| allDrawn || mAppAnimator.allDrawn) {
245245
pw.print(prefix); pw.print("numInterestingWindows=");
246246
pw.print(numInterestingWindows);
247247
pw.print(" numDrawnWindows="); pw.print(numDrawnWindows);
248248
pw.print(" inPendingTransaction="); pw.print(inPendingTransaction);
249-
pw.print(" allDrawn="); pw.println(allDrawn);
249+
pw.print(" allDrawn="); pw.print(allDrawn);
250+
pw.print(" (animator="); pw.print(mAppAnimator.allDrawn);
251+
pw.println(")");
252+
}
253+
if (inPendingTransaction) {
254+
pw.print(prefix); pw.print("inPendingTransaction=");
255+
pw.println(inPendingTransaction);
250256
}
251257
if (startingData != null || removed || firstWindowDrawn) {
252258
pw.print(prefix); pw.print("startingData="); pw.print(startingData);

services/java/com/android/server/wm/WindowAnimator.java

Lines changed: 54 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ public class WindowAnimator {
3838
ArrayList<WindowStateAnimator> mWinAnimators = new ArrayList<WindowStateAnimator>();
3939

4040
boolean mAnimating;
41-
boolean mTokenMayBeDrawn;
4241
boolean mForceHiding;
4342
WindowState mWindowAnimationBackground;
4443
int mWindowAnimationBackgroundColor;
@@ -57,7 +56,7 @@ public class WindowAnimator {
5756

5857
/** Skip repeated AppWindowTokens initialization. Note that AppWindowsToken's version of this
5958
* is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */
60-
private int mTransactionSequence;
59+
private int mAnimTransactionSequence;
6160

6261
/** The one and only screen rotation if one is happening */
6362
ScreenRotationAnimation mScreenRotationAnimation = null;
@@ -194,7 +193,7 @@ private void updateWindowsAppsAndRotationAnimationsLocked() {
194193
}
195194

196195
private void updateWindowsAndWallpaperLocked() {
197-
++mTransactionSequence;
196+
++mAnimTransactionSequence;
198197

199198
ArrayList<WindowStateAnimator> unForceHiding = null;
200199
boolean wallpaperInUnForceHiding = false;
@@ -332,59 +331,22 @@ private void updateWindowsAndWallpaperLocked() {
332331
}
333332

334333
final AppWindowToken atoken = win.mAppToken;
335-
if (atoken != null && (!atoken.allDrawn || atoken.mAppAnimator.freezingScreen)) {
336-
if (atoken.lastTransactionSequence != mTransactionSequence) {
337-
atoken.lastTransactionSequence = mTransactionSequence;
338-
atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
339-
atoken.startingDisplayed = false;
340-
}
341-
if ((win.isOnScreen() || winAnimator.mAttrType
342-
== WindowManager.LayoutParams.TYPE_BASE_APPLICATION)
343-
&& !win.mExiting && !win.mDestroying) {
344-
if (WindowManagerService.DEBUG_VISIBILITY ||
345-
WindowManagerService.DEBUG_ORIENTATION) {
346-
Slog.v(TAG, "Eval win " + win + ": isDrawn=" + win.isDrawnLw()
347-
+ ", isAnimating=" + winAnimator.isAnimating());
348-
if (!win.isDrawnLw()) {
349-
Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurface
350-
+ " pv=" + win.mPolicyVisibility
351-
+ " mDrawState=" + winAnimator.mDrawState
352-
+ " ah=" + win.mAttachedHidden
353-
+ " th=" + atoken.hiddenRequested
354-
+ " a=" + winAnimator.mAnimating);
355-
}
356-
}
357-
if (win != atoken.startingWindow) {
358-
if (!atoken.mAppAnimator.freezingScreen || !win.mAppFreezing) {
359-
atoken.numInterestingWindows++;
360-
if (win.isDrawnLw()) {
361-
atoken.numDrawnWindows++;
362-
if (WindowManagerService.DEBUG_VISIBILITY ||
363-
WindowManagerService.DEBUG_ORIENTATION) Slog.v(TAG,
364-
"tokenMayBeDrawn: " + atoken
365-
+ " freezingScreen=" + atoken.mAppAnimator.freezingScreen
366-
+ " mAppFreezing=" + win.mAppFreezing);
367-
mTokenMayBeDrawn = true;
368-
}
334+
if (winAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW) {
335+
if (atoken == null || atoken.allDrawn) {
336+
if (winAnimator.performShowLocked()) {
337+
mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
338+
if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
339+
mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 5",
340+
mPendingLayoutChanges);
369341
}
370-
} else if (win.isDrawnLw()) {
371-
atoken.startingDisplayed = true;
372-
}
373-
}
374-
} else if (winAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW) {
375-
if (winAnimator.performShowLocked()) {
376-
mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
377-
if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
378-
mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 5",
379-
mPendingLayoutChanges);
380342
}
381343
}
382344
}
383345
final AppWindowAnimator appAnimator =
384346
atoken == null ? null : atoken.mAppAnimator;
385347
if (appAnimator != null && appAnimator.thumbnail != null) {
386-
if (appAnimator.thumbnailTransactionSeq != mTransactionSequence) {
387-
appAnimator.thumbnailTransactionSeq = mTransactionSequence;
348+
if (appAnimator.thumbnailTransactionSeq != mAnimTransactionSequence) {
349+
appAnimator.thumbnailTransactionSeq = mAnimTransactionSequence;
388350
appAnimator.thumbnailLayer = 0;
389351
}
390352
if (appAnimator.thumbnailLayer < winAnimator.mAnimLayer) {
@@ -414,47 +376,39 @@ private void testTokenMayBeDrawnLocked() {
414376
final int NT = appTokens.size();
415377
for (int i=0; i<NT; i++) {
416378
AppWindowToken wtoken = appTokens.get(i);
417-
if (wtoken.mAppAnimator.freezingScreen) {
418-
int numInteresting = wtoken.numInterestingWindows;
419-
if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
420-
if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
421-
"allDrawn: " + wtoken
422-
+ " interesting=" + numInteresting
423-
+ " drawn=" + wtoken.numDrawnWindows);
424-
wtoken.mAppAnimator.showAllWindowsLocked();
425-
mService.unsetAppFreezingScreenLocked(wtoken, false, true);
426-
if (WindowManagerService.DEBUG_ORIENTATION) Slog.i(TAG,
427-
"Setting mOrientationChangeComplete=true because wtoken "
428-
+ wtoken + " numInteresting=" + numInteresting
429-
+ " numDrawn=" + wtoken.numDrawnWindows);
430-
// This will set mOrientationChangeComplete and cause a pass through layout.
431-
mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
432-
}
433-
} else if (!wtoken.allDrawn) {
434-
int numInteresting = wtoken.numInterestingWindows;
435-
if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
436-
if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
437-
"allDrawn: " + wtoken
438-
+ " interesting=" + numInteresting
439-
+ " drawn=" + wtoken.numDrawnWindows);
440-
wtoken.allDrawn = true;
441-
mPendingLayoutChanges |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
442-
if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
443-
mService.debugLayoutRepeats("testTokenMayBeDrawnLocked",
444-
mPendingLayoutChanges);
445-
}
379+
final boolean allDrawn = wtoken.allDrawn;
380+
if (allDrawn != wtoken.mAppAnimator.allDrawn) {
381+
wtoken.mAppAnimator.allDrawn = allDrawn;
382+
if (allDrawn) {
383+
// The token has now changed state to having all
384+
// windows shown... what to do, what to do?
385+
if (wtoken.mAppAnimator.freezingScreen) {
386+
wtoken.mAppAnimator.showAllWindowsLocked();
387+
mService.unsetAppFreezingScreenLocked(wtoken, false, true);
388+
if (WindowManagerService.DEBUG_ORIENTATION) Slog.i(TAG,
389+
"Setting mOrientationChangeComplete=true because wtoken "
390+
+ wtoken + " numInteresting=" + wtoken.numInterestingWindows
391+
+ " numDrawn=" + wtoken.numDrawnWindows);
392+
// This will set mOrientationChangeComplete and cause a pass through layout.
393+
mPendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
394+
} else {
395+
mPendingLayoutChanges |= PhoneWindowManager.FINISH_LAYOUT_REDO_ANIM;
396+
if (WindowManagerService.DEBUG_LAYOUT_REPEATS) {
397+
mService.debugLayoutRepeats("testTokenMayBeDrawnLocked",
398+
mPendingLayoutChanges);
399+
}
446400

447-
// We can now show all of the drawn windows!
448-
if (!mService.mOpeningApps.contains(wtoken)) {
449-
mAnimating |= wtoken.mAppAnimator.showAllWindowsLocked();
401+
// We can now show all of the drawn windows!
402+
if (!mService.mOpeningApps.contains(wtoken)) {
403+
mAnimating |= wtoken.mAppAnimator.showAllWindowsLocked();
404+
}
450405
}
451406
}
452407
}
453408
}
454409
}
455410

456411
private void performAnimationsLocked() {
457-
mTokenMayBeDrawn = false;
458412
mForceHiding = false;
459413
mDetachedWallpaper = null;
460414
mWindowAnimationBackground = null;
@@ -465,9 +419,7 @@ private void performAnimationsLocked() {
465419
mPendingActions |= WALLPAPER_ACTION_PENDING;
466420
}
467421

468-
if (mTokenMayBeDrawn) {
469-
testTokenMayBeDrawnLocked();
470-
}
422+
testTokenMayBeDrawnLocked();
471423
}
472424

473425
synchronized void animate() {
@@ -584,18 +536,23 @@ boolean isDimming(final WindowStateAnimator winAnimator) {
584536
}
585537

586538
public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
587-
if (mWindowDetachedWallpaper != null) {
588-
pw.print(" mWindowDetachedWallpaper="); pw.println(mWindowDetachedWallpaper);
589-
}
590-
if (mWindowAnimationBackgroundSurface != null) {
591-
pw.println(" mWindowAnimationBackgroundSurface:");
592-
mWindowAnimationBackgroundSurface.printTo(" ", pw);
593-
}
594-
if (mDimAnimator != null) {
595-
pw.println(" mDimAnimator:");
596-
mDimAnimator.printTo(" ", pw);
597-
} else {
598-
pw.println( " no DimAnimator ");
539+
if (dumpAll) {
540+
if (mWindowDetachedWallpaper != null) {
541+
pw.print(prefix); pw.print("mWindowDetachedWallpaper=");
542+
pw.println(mWindowDetachedWallpaper);
543+
}
544+
pw.print(prefix); pw.print("mAnimTransactionSequence=");
545+
pw.println(mAnimTransactionSequence);
546+
if (mWindowAnimationBackgroundSurface != null) {
547+
pw.print(prefix); pw.print("mWindowAnimationBackgroundSurface:");
548+
mWindowAnimationBackgroundSurface.printTo(prefix + " ", pw);
549+
}
550+
if (mDimAnimator != null) {
551+
pw.print(prefix); pw.print("mDimAnimator:");
552+
mDimAnimator.printTo(prefix + " ", pw);
553+
} else {
554+
pw.print(prefix); pw.print("no DimAnimator ");
555+
}
599556
}
600557
}
601558

0 commit comments

Comments
 (0)