存在一个问题:负载指纹响应时间衰退达到1秒多,从log中看Waiting for drawn Window 耗时太长
Line 3204: 08-14 14:44:45.929433 1100 5600 I PowerManagerService: Waking up from sleep (uid=10028 reason=android.policy:FINGERPRINT)...
Line 3211: 08-14 14:44:45.939175 1100 1135 I DisplayPowerController: Blocking screen on until initial contents have been drawn.
///Launcher 处于DRAW_PENDING 状态,这是一个surface已经创建但是Window还没draw的状态
Line 3250: 08-14 14:44:46.462380 1100 1121 I WindowManager: Waiting for drawn Window{f9de4b3 u0 com.android.launcher3/com.android.launcher3.Launcher}: removed=false visible=true mHasSurface=true drawState=1
Line 3251: 08-14 14:44:46.462434 1100 1121 I WindowManager: Waiting for drawn Window{18b56d9 u0 StatusBar}: removed=false visible=true mHasSurface=true drawState=1
///StatusBar HAS_DRAWN 完成绘制
Line 3276: 08-14 14:44:46.757318 1100 1176 I WindowManager: Waiting for drawn Window{18b56d9 u0 StatusBar}: removed=false visible=true mHasSurface=true drawState=4
....
///Launcher 绘制完成持续时间比较久,从14:44:46.462380持续到14:44:47.221558,耗时接近800毫秒
Line 3298: 08-14 14:44:47.221558 1100 1176 I WindowManager: Waiting for drawn Window{f9de4b3 u0 com.android.launcher3/com.android.launcher3.Launcher}: removed=false visible=true mHasSurface=true drawState=4
08-14 14:44:47.221628 1100 1176 D WindowManager: Window drawn win=Window{f9de4b3 u0 com.android.launcher3/com.android.launcher3.Launcher}
08-14 14:44:47.221644 1100 1176 D WindowManager: All windows drawn!
08-14 14:44:47.252180 1100 1135 I DisplayPowerController: Unblocked screen on after 1313 ms
///这一次power screen on 耗时1.33S
08-14 14:44:47.257309 1100 1135 W PowerManagerService: Screen on took 1330 ms
如上log中drawstate有五个状态,一般是从DRAW_PENDING 开始等待到HAS_DRAWN这一段耗时太长。
/frameworks/base/services/core/java/com/android/server/wm/WindowStateAnimator.java
/** This is set when there is no Surface */
static final int NO_SURFACE = 0;
/** This is set after the Surface has been created but before the window has been drawn. During
* this time the surface is hidden. */
static final int DRAW_PENDING = 1;
/** This is set after the window has finished drawing for the first time but before its surface
* is shown. The surface will be displayed when the next layout is run. */
static final int COMMIT_DRAW_PENDING = 2;
/** This is set during the time after the window's drawing has been committed, and before its
* surface is actually shown. It is used to delay showing the surface until all windows in a
* token are ready to be shown. */
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;
往下再看一下DRAW_PENDING和HAS_DRAWN分别是在哪边赋值的。
/frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java
void waitForAllWindowsDrawn() {
final WindowManagerPolicy policy = mService.mPolicy;
forAllWindows(w -> {
final boolean keyguard = policy.isKeyguardHostWindow(w.mAttrs);
if (w.isVisibleLw() && (w.mAppToken != null || keyguard)) {
w.mWinAnimator.mDrawState = DRAW_PENDING;
// Force add to mResizingWindows.
w.mLastContentInsets.set(-1, -1, -1, -1);
mService.mWaitingForDrawn.add(w);
}
}, true /* traverseTopToBottom */);
}
三个调用的点
1.MSG_KEYGUARD_DRAWN_COMPLETE,
2.MSG_KEYGUARD_DRAWN_TIMEOUT,
3.screenTurningOn
----->PhoneWindowManger.finishKeyguardDrawn----->WindowManagerService.waitForAllWindowsDrawn---->DisplayContent.waitForAllWindowsDrawn
在WindowManagerService的waitForAllWindowsDrawn中
@Override
public void waitForAllWindowsDrawn(Runnable callback, long timeout) {
boolean allWindowsDrawn = false;
synchronized (mWindowMap) {
mWaitingForDrawnCallback = callback;
//即对应的DisplayContent的waitForAllWindowsDrawn
getDefaultDisplayContentLocked().waitForAllWindowsDrawn();
//AnimationThread 线程post了一个mPerformSurfacePlacement Runnable,
//mAnimationHandler收到这个消息后,performSurfacePlacement()方法就会
//执行,接着调用 performSurfacePlacementLoop->RootWindowContainer.performSurfacePlacement,
//AnimationThread 继承 HandlerThread 一个带Looper 的Thread
mWindowPlacerLocked.requestTraversal();
mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT);
if (mWaitingForDrawn.isEmpty()) {
allWindowsDrawn = true;
} else {
mH.sendEmptyMessageDelayed(H.WAITING_FOR_DRAWN_TIMEOUT, timeout);
checkDrawnWindowsLocked();
}
}
if (allWindowsDrawn) {
callback.run();
}
}
//WindowSurfacePlacer.java
void requestTraversal() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
mService.mAnimationHandler.post(mPerformSurfacePlacement);
}
}
其中等待绘制的界面不为空走checkDrawnWindowsLocked
void checkDrawnWindowsLocked() {
if (mWaitingForDrawn.isEmpty() || mWaitingForDrawnCallback == null) {
return;
}
for (int j = mWaitingForDrawn.size() - 1; j >= 0; j--) {
WindowState win = mWaitingForDrawn.get(j);
if (DEBUG_SCREEN_ON) Slog.i(TAG_WM, "Waiting for drawn " + win +
": removed=" + win.mRemoved + " visible=" + win.isVisibleLw() +
" mHasSurface=" + win.mHasSurface +
" drawState=" + win.mWinAnimator.mDrawState);
if (win.mRemoved || !win.mHasSurface || !win.mPolicyVisibility) {
// Window has been removed or hidden; no draw will now happen, so stop waiting.
if (DEBUG_SCREEN_ON) Slog.w(TAG_WM, "Aborted waiting for drawn: " + win);
mWaitingForDrawn.remove(win);
} else if (win.hasDrawnLw()) {//即等于HAS_DRAWN状态会将win删除
// Window is now drawn (and shown).
if (DEBUG_SCREEN_ON) Slog.d(TAG_WM, "Window drawn win=" + win);
mWaitingForDrawn.remove(win);
}
}
if (mWaitingForDrawn.isEmpty()) {
if (DEBUG_SCREEN_ON) Slog.d(TAG_WM, "All windows drawn!");
mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT);
mH.sendEmptyMessage(H.ALL_WINDOWS_DRAWN);
}
}
而HAS_DRAWN在frameworks/base/services/core/java/com/android/server/wm/WindowState.java
// This must be called while inside a transaction.
boolean performShowLocked() {
if (isHiddenFromUserLocked()) {
if (DEBUG_VISIBILITY) Slog.w(TAG, "hiding " + this + ", belonging to " + mOwnerUid);
hideLw(false);
return false;
}
logPerformShow("performShow on ");
final int drawState = mWinAnimator.mDrawState;
if ((drawState == HAS_DRAWN || drawState == READY_TO_SHOW)
&& mAttrs.type != TYPE_APPLICATION_STARTING && mAppToken != null) {
mAppToken.onFirstWindowDrawn(this, mWinAnimator);
}
if (mWinAnimator.mDrawState != READY_TO_SHOW || !isReadyForDisplay()) {
return false;
}
logPerformShow("Showing ");
mService.enableScreenIfNeededLocked();
mWinAnimator.applyEnterAnimationLocked();
// Force the show in the next prepareSurfaceLocked() call.
mWinAnimator.mLastAlpha = -1;
if (DEBUG_ANIM) Slog.v(TAG,
"performShowLocked: mDrawState=HAS_DRAWN in " + this);
mWinAnimator.mDrawState = HAS_DRAWN;
mService.scheduleAnimationLocked();
if (mHidden) {
mHidden = false;
final DisplayContent displayContent = getDisplayContent();
for (int i = mChildren.size() - 1; i >= 0; --i) {
final WindowState c = mChildren.get(i);
if (c.mWinAnimator.mSurfaceController != null) {
c.performShowLocked();
// It hadn't been shown, which means layout not performed on it, so now we
// want to make sure to do a layout. If called from within the transaction
// loop, this will cause it to restart with a new layout.
if (displayContent != null) {
displayContent.setLayoutNeeded();
}
}
}
}
if (mAttrs.type == TYPE_INPUT_METHOD) {
getDisplayContent().mDividerControllerLocked.resetImeHideRequested();
}
return true;
}
HAS_DRAWN打印的堆栈
11-07 07:34:46.279 V/WindowManager( 1039): performShowLocked: mDrawState=HAS_DRAWN in Window{b848e17 u0 StatusBar}
11-07 07:34:46.279 V/WindowManager( 1039): java.lang.Throwable
11-07 07:34:46.279 V/WindowManager( 1039): at com.android.server.wm.WindowState.performShowLocked(WindowState.java:3995)
11-07 07:34:46.279 V/WindowManager( 1039): at com.android.server.wm.WindowStateAnimator.commitFinishDrawingLocked(WindowStateAnimator.java:357)
11-07 07:34:46.279 V/WindowManager( 1039): at com.android.server.wm.DisplayContent.lambda$new$8$DisplayContent(DisplayContent.java:843)
11-07 07:34:46.279 V/WindowManager( 1039): at com.android.server.wm.-$$Lambda$DisplayContent$qxt4izS31fb0LF2uo_OF9DMa7gc.accept(Unknown Source:4)
11-07 07:34:46.279 V/WindowManager( 1039): at com.android.server.wm.WindowContainer$ForAllWindowsConsumerWrapper.apply(WindowContainer.java:1184)
11-07 07:34:46.279 V/WindowManager( 1039): at com.android.server.wm.WindowContainer$ForAllWindowsConsumerWrapper.apply(WindowContainer.java:1174)
11-07 07:34:46.279 V/WindowManager( 1039): at com.android.server.wm.WindowState.applyInOrderWithImeWindows(WindowState.java:4194)
11-07 07:34:46.279 V/WindowManager( 1039): at com.android.server.wm.WindowState.forAllWindows(WindowState.java:4093)
11-07 07:34:46.279 V/WindowManager( 1039): at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:883)
11-07 07:34:46.279 V/WindowManager( 1039): at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:883)
11-07 07:34:46.279 V/WindowManager( 1039): at com.android.server.wm.DisplayContent.forAllWindows(DisplayContent.java:2149)
11-07 07:34:46.279 V/WindowManager( 1039): at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:900)
11-07 07:34:46.279 V/WindowManager( 1039): at com.android.server.wm.DisplayContent.applySurfaceChangesTransaction(DisplayContent.java:3778)
11-07 07:34:46.279 V/WindowManager( 1039): at com.android.server.wm.RootWindowContainer.applySurfaceChangesTransaction(RootWindowContainer.java:834)
11-07 07:34:46.279 V/WindowManager( 1039): at com.android.server.wm.RootWindowContainer.performSurfacePlacementNoTrace(RootWindowContainer.java:611)
11-07 07:34:46.279 V/WindowManager( 1039): at com.android.server.wm.RootWindowContainer.performSurfacePlacement(RootWindowContainer.java:568)
11-07 07:34:46.279 V/WindowManager( 1039): at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacementLoop(WindowSurfacePlacer.java:159)
11-07 07:34:46.279 V/WindowManager( 1039): at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement(WindowSurfacePlacer.java:105)
11-07 07:34:46.279 V/WindowManager( 1039): at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement(WindowSurfacePlacer.java:95)
11-07 07:34:46.279 V/WindowManager( 1039): at com.android.server.wm.WindowSurfacePlacer.lambda$new$0$WindowSurfacePlacer(WindowSurfacePlacer.java:62)
WindowAnimator.animate----->WindowContainer.checkAppWindowsReadyToShow--->AppWindowToken.checkAppWindowsReadyToShow--->AppWindowToken.showAllWindowsLocked---->WindowState.performShowLocked
/** Checks if all windows in an app are all drawn and shows them if needed. */
void checkAppWindowsReadyToShow() {
for (int i = mChildren.size() - 1; i >= 0; --i) {
final WindowContainer wc = mChildren.get(i);
wc.checkAppWindowsReadyToShow();
}
}
/**
* DO NOT HOLD THE WINDOW MANAGER LOCK WHILE CALLING THIS METHOD. Reason: the method closes
* an animation transaction, that might be blocking until the next sf-vsync, so we want to make
* sure other threads can make progress if this happens.
*/
private void animate(long frameTimeNs) {
....
synchronized (mService.mWindowMap) {
if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION animate");
mService.openSurfaceTransaction();
.....
final int numDisplays = mDisplayContentsAnimators.size();
for (int i = 0; i < numDisplays; i++) {
final int displayId = mDisplayContentsAnimators.keyAt(i);
final DisplayContent dc = mService.mRoot.getDisplayContent(displayId);
DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i);
final ScreenRotationAnimation screenRotationAnimation =
displayAnimator.mScreenRotationAnimation;
if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) {
if (screenRotationAnimation.stepAnimationLocked(mCurrentTime)) {
setAnimating(true);
} else {
mBulkUpdateParams |= SET_UPDATE_ROTATION;
screenRotationAnimation.kill();
displayAnimator.mScreenRotationAnimation = null;
//TODO (multidisplay): Accessibility supported only for the default
// display.
if (accessibilityController != null && dc.isDefaultDisplay) {
// We just finished rotation animation which means we did not
// announce the rotation and waited for it to end, announce now.
accessibilityController.onRotationChangedLocked(
mService.getDefaultDisplayContentLocked());
}
}
}
// Update animations of all applications, including those
// associated with exiting/removed apps
++mAnimTransactionSequence;
dc.updateWindowsForAnimator(this);
dc.updateWallpaperForAnimator(this);
dc.prepareSurfaces();
}
....
for (int i = 0; i < numDisplays; i++) {
final int displayId = mDisplayContentsAnimators.keyAt(i);
final DisplayContent dc = mService.mRoot.getDisplayContent(displayId);
dc.checkAppWindowsReadyToShow();
final ScreenRotationAnimation screenRotationAnimation =
mDisplayContentsAnimators.valueAt(i).mScreenRotationAnimation;
if (screenRotationAnimation != null) {
screenRotationAnimation.updateSurfaces(mTransaction);
}
orAnimating(dc.getDockedDividerController().animate(mCurrentTime));
//TODO (multidisplay): Magnification is supported only for the default display.
if (accessibilityController != null && dc.isDefaultDisplay) {
accessibilityController.drawMagnifiedRegionBorderIfNeededLocked();
}
}
if (!mAnimating) {
cancelAnimation();
}
if (mService.mWatermark != null) {
mService.mWatermark.drawIfNeeded();
}
SurfaceControl.mergeToGlobalTransaction(mTransaction);
}finally {
mService.closeSurfaceTransaction("WindowAnimator");
if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION animate");
}
....
}
....
}
READY_TO_SHOW的赋值点
1.WindowSurfacePlacer.performSurfacePlacementLoop(){
mService.mRoot.performSurfacePlacement(recoveringMemory);
}
2.DisplayContent.updateFocusedWindowLocked(){
mWmService.mRoot.performSurfacePlacement(false);
}
///
RootWindowContainer.performSurfacePlacement(boolean recoveringMemory)-->
RootWindowContainer.performSurfacePlacementNoTrace{ applySurfaceChangesTransaction(recoveringMemory);}
-->
RootWindowContainer.applySurfaceChangesTransaction{
830 final int count = mChildren.size();
831 for (int j = 0; j < count; ++j) {
832 final DisplayContent dc = mChildren.get(j);
833 dc.applySurfaceChangesTransaction(recoveringMemory);
834 }
}
-->
DisplayContent.applySurfaceChangesTransaction{forAllWindows(mApplySurfaceChangesTransaction, true /* traverseTopToBottom */);}
-->
DisplayContent.mApplySurfaceChangesTransaction = w ->
-->
WindowStateAnimator.commitFinishDrawingLocked{ mDrawState = READY_TO_SHOW;}
--->
WindowState.performShowLocked { mDrawState=HAS_DRAWN }--->
READY_TO_SHOW打印的堆栈
11-07 07:34:46.274 I/WindowManager( 1039): commitFinishDrawingLocked: mDrawState=READY_TO_SHOW Surface(name=StatusBar)/@0x1e834ef
11-07 07:34:46.274 I/WindowManager( 1039): java.lang.Throwable
11-07 07:34:46.274 I/WindowManager( 1039): at com.android.server.wm.WindowStateAnimator.commitFinishDrawingLocked(WindowStateAnimator.java:350)
11-07 07:34:46.274 I/WindowManager( 1039): at com.android.server.wm.DisplayContent.lambda$new$8$DisplayContent(DisplayContent.java:843)
11-07 07:34:46.274 I/WindowManager( 1039): at com.android.server.wm.-$$Lambda$DisplayContent$qxt4izS31fb0LF2uo_OF9DMa7gc.accept(Unknown Source:4)
11-07 07:34:46.274 I/WindowManager( 1039): at com.android.server.wm.WindowContainer$ForAllWindowsConsumerWrapper.apply(WindowContainer.java:1184)
11-07 07:34:46.274 I/WindowManager( 1039): at com.android.server.wm.WindowContainer$ForAllWindowsConsumerWrapper.apply(WindowContainer.java:1174)
11-07 07:34:46.274 I/WindowManager( 1039): at com.android.server.wm.WindowState.applyInOrderWithImeWindows(WindowState.java:4194)
11-07 07:34:46.274 I/WindowManager( 1039): at com.android.server.wm.WindowState.forAllWindows(WindowState.java:4093)
11-07 07:34:46.274 I/WindowManager( 1039): at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:883)
11-07 07:34:46.274 I/WindowManager( 1039): at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:883)
11-07 07:34:46.274 I/WindowManager( 1039): at com.android.server.wm.DisplayContent.forAllWindows(DisplayContent.java:2149)
11-07 07:34:46.274 I/WindowManager( 1039): at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:900)
11-07 07:34:46.274 I/WindowManager( 1039): at com.android.server.wm.DisplayContent.applySurfaceChangesTransaction(DisplayContent.java:3778)
11-07 07:34:46.274 I/WindowManager( 1039): at com.android.server.wm.RootWindowContainer.applySurfaceChangesTransaction(RootWindowContainer.java:834)
11-07 07:34:46.274 I/WindowManager( 1039): at com.android.server.wm.RootWindowContainer.performSurfacePlacementNoTrace(RootWindowContainer.java:611)
11-07 07:34:46.274 I/WindowManager( 1039): at com.android.server.wm.RootWindowContainer.performSurfacePlacement(RootWindowContainer.java:568)
11-07 07:34:46.274 I/WindowManager( 1039): at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacementLoop(WindowSurfacePlacer.java:159)
11-07 07:34:46.274 I/WindowManager( 1039): at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement(WindowSurfacePlacer.java:105)
11-07 07:34:46.274 I/WindowManager( 1039): at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement(WindowSurfacePlacer.java:95)
11-07 07:34:46.274 I/WindowManager( 1039): at com.android.server.wm.WindowSurfacePlacer.lambda$new$0$WindowSurfacePlacer(WindowSurfacePlacer.java:62)
一个有锁屏界面按Power键亮屏的界面绘制流程log
08-21 03:04:57.616 I/PowerManagerService( 1025): Waking up from sleep (uid=1000 reason=android.policy:POWER)...
08-21 03:04:57.619 I/DisplayPowerController( 1025): Blocking screen on until initial contents have been drawn.
08-21 03:04:57.703 I/WindowManager( 1025): Waiting for drawn Window{94a4fbd u0 StatusBar}: removed=false visible=true mHasSurface=true drawState=1
....
08-21 03:04:57.736 I/WindowManager( 1025): Waiting for drawn Window{94a4fbd u0 StatusBar}: removed=false visible=true mHasSurface=true drawState=1
08-21 03:04:57.746 D/WindowManager( 1025): finishDrawingWindow: Window{c72bd2b u0 SmartPanel_SliderView} mDrawState=HAS_DRAWN
08-21 03:04:57.765 D/WindowManager( 1025): finishDrawingWindow: Window{94a4fbd u0 StatusBar} mDrawState=DRAW_PENDING
08-21 03:04:57.766 W/WindowManager( 1025): setLayoutNeeded: callers=com.android.server.wm.WindowState.setDisplayLayoutNeeded:2312 com.android.server.wm.WindowManagerService.finishDrawingWindow:2441 com.android.server.wm.Session.finishDrawing:282
08-21 03:04:57.766 V/WindowManager( 1025): performSurfacePlacementInner: entry. Called by com.android.server.wm.WindowSurfacePlacer.performSurfacePlacementLoop:208 com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement:156 com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement:146
08-21 03:04:57.766 I/WindowManager( 1025): >>> OPEN TRANSACTION performLayoutAndPlaceSurfaces
....
08-21 03:04:57.772 I/WindowManager( 1025): commitFinishDrawingLocked: mDrawState=READY_TO_SHOW Surface(name=StatusBar)/@0x6490d9c
08-21 03:04:57.772 V/WindowManager( 1025): performShow on Window{94a4fbd u0 StatusBar}: mDrawState=READY_TO_SHOW readyForDisplay=true starting=false during animation: policyVis=true parentHidden=false tok.hiddenRequested=false tok.hidden=false animationSet=false tok animating=false Callers=com.android.server.wm.WindowState.performShowLocked:3891
....
08-21 03:04:57.773 V/WindowManager( 1025): applyAnimation: win=WindowStateAnimator{f7df172 StatusBar} anim=-1 attr=0xffffffff a=null transit=3 isEntrance=true Callers
08-21 03:04:57.773 V/WindowManager( 1025): performShowLocked: mDrawState=HAS_DRAWN in Window{94a4fbd u0 StatusBar}
...
08-21 03:04:57.776 I/WindowManager( 1025): <<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces
...
08-21 03:04:57.777 I/WindowManager( 1025): Waiting for drawn Window{94a4fbd u0 StatusBar}: removed=false visible=true mHasSurface=true drawState=4
08-21 03:04:57.885 W/PowerManagerService( 1025): Screen on took 278 ms
log中>>> OPEN TRANSACTION performLayoutAndPlaceSurfaces和<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces对应的是
/frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
void performSurfacePlacement(boolean recoveringMemory) {
.....
if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
mService.openSurfaceTransaction();
try {
applySurfaceChangesTransaction(recoveringMemory, defaultDw, defaultDh);
} catch (RuntimeException e) {
Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
} finally {
mService.closeSurfaceTransaction("performLayoutAndPlaceSurfaces");
if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
"<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
}
....
mService.mAnimator.executeAfterPrepareSurfacesRunnables();
final WindowSurfacePlacer surfacePlacer = mService.mWindowPlacerLocked;
// If we are ready to perform an app transition, check through all of the app tokens to be
// shown and see if they are ready to go.
if (mService.mAppTransition.isReady()) {
// This needs to be split into two expressions, as handleAppTransitionReadyLocked may
// modify dc.pendingLayoutChanges, which would get lost when writing
// defaultDisplay.pendingLayoutChanges |= handleAppTransitionReadyLocked()
final int layoutChanges = surfacePlacer.handleAppTransitionReadyLocked();
defaultDisplay.pendingLayoutChanges |= layoutChanges;
if (DEBUG_LAYOUT_REPEATS)
surfacePlacer.debugLayoutRepeats("after handleAppTransitionReadyLocked",
defaultDisplay.pendingLayoutChanges);
}
....
....
}
ViewRootImpl.scheduleTraversals(-->
mTraversalRunnable-->
ViewRootImpl.performTraversals-->
ViewRootImpl.performDraw--->
ViewRootImpl.pendingDrawFinished---->
ViewRootImpl.reportDrawFinished--->
mWindowSession.finishDrawing(mWindow)--->
Session.finishDrawing---->
WindowManagerService.finishDrawingWindow--->
void finishDrawingWindow(Session session, IWindow client) {
final long origId = Binder.clearCallingIdentity();
try {
synchronized (mWindowMap) {
WindowState win = windowForClientLocked(session, client, false);
if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "finishDrawingWindow: " + win + " mDrawState="
+ (win != null ? win.mWinAnimator.drawStateToString() : "null"));
if (win != null && win.mWinAnimator.finishDrawingLocked()) {
if ((win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
win.getDisplayContent().pendingLayoutChanges |=
WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
}
win.setDisplayLayoutNeeded();
mWindowPlacerLocked.requestTraversal();
}
}
} finally {
Binder.restoreCallingIdentity(origId);
}
}