调用流程如下:
/frameworks/base/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
performSurfacePlacement -> performSurfacePlacementLoop -> isLayoutNeeded -> requestTraversal -> mAnimationHandler.post(runnable) -> 持wms锁 -> performSurfacePlacement() ->
如果一个window连续layout的次数超过6,打印log :WindowManager: Performed 6 layouts in a row. Skipping
/
WindowSurfacePlacer{
mPerformSurfacePlacement = () -> {
synchronized (mService.mWindowMap) {
performSurfacePlacement();
}
};
}
--->performSurfacePlacement-->
{
int loopCount = 6;
do {
mTraversalScheduled = false;
performSurfacePlacementLoop();
mService.mAnimationHandler.removeCallbacks(mPerformSurfacePlacement);
loopCount--;
} while (mTraversalScheduled && loopCount > 0);
}
--->performSurfacePlacementLoop-->
{
mService.mRoot.performSurfacePlacement(recoveringMemory);//处理relayout的核心方法
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmLayout");
1. if (mService.mRoot.isLayoutNeeded()) {
if (++mLayoutRepeatCount < 6) {
2. requestTraversal();
} else {
Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
mLayoutRepeatCount = 0;
}
} else {
mLayoutRepeatCount = 0;
}
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
}
1.--->RootWindowContainer-->isLayoutNeeded{
final int numDisplays = mChildren.size();
for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
final DisplayContent displayContent = mChildren.get(displayNdx);
3. if (displayContent.isLayoutNeeded()) {
return true;
}
}
return false;
}
}
///
2-->requestTraversal
void requestTraversal() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
mService.mAnimationHandler.post(mPerformSurfacePlacement);
}
}
private final Runnable mPerformSurfacePlacement;
public WindowSurfacePlacer(WindowManagerService service) {
mService = service;
mPerformSurfacePlacement = () -> {
synchronized (mService.mGlobalLock) {
performSurfacePlacement();///循环操作
}
};
}
///
3--->DisplayContent.isLayoutNeeded.mLayoutNeeded
DisplayContent.setLayoutNeeded{
mLayoutNeeded = true;
}
/frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
performSurfacePlacement-->performSurfacePlacementNoTrace{
.....
581 if (mWmService.mFocusMayChange) {
582 mWmService.mFocusMayChange = false;
583 mWmService.updateFocusedWindowLocked(
584 UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
585 }
....
....
605 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
606 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
607 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applySurfaceChanges");
//openTransaction和closeTransaction之间是对surface进行操作,建立和SurfaceFlinger通信,
//如setSize,setLayer,setPosition等都不是及时生效的,而是要等到业务关闭之后才统一通知
//SurfaceFlinger,可以避免属性过快带来的画面不稳定
608 mWmService.openSurfaceTransaction();
609 try {
//计算窗口大小及完成窗口动画
610 applySurfaceChangesTransaction(recoveringMemory);
611 } catch (RuntimeException e) {
612 Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
613 } finally {
614 mWmService.closeSurfaceTransaction("performLayoutAndPlaceSurfaces");
615 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
616 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
617 "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
618 }
619 mWmService.mAnimator.executeAfterPrepareSurfacesRunnables();
....
654 handleResizingWindows();
}
RootWindowContainer.applySurfaceChangesTransaction--->
private void applySurfaceChangesTransaction(boolean recoveringMemory) {
....
//遍历mChildren
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 }
835
836 // Give the display manager a chance to adjust properties like display rotation if it needs
837 // to.
838 mWmService.mDisplayManagerInternal.performTraversal(mDisplayTransaction);
839 SurfaceControl.mergeToGlobalTransaction(mDisplayTransaction);
....
}
/frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java
3715 // TODO: Super crazy long method that should be broken down...
3716 void applySurfaceChangesTransaction(boolean recoveringMemory) {
3721 int repeats = 0;
3722 do {
3723 repeats++;
3724 if (repeats > 6) {
3725 Slog.w(TAG, "Animation repeat aborted after too many iterations");
3726 clearLayoutNeeded();
3727 break;
3728 }
3730 if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats("On entry to LockedInner",
3731 pendingLayoutChanges);
....
....
///
3733 if ((pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
3734 mWallpaperController.adjustWallpaperWindows();
3735 }
3736
3737 if ((pendingLayoutChanges & FINISH_LAYOUT_REDO_CONFIG) != 0) {
3738 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
3739 if (updateOrientationFromAppTokens()) {
3740 setLayoutNeeded();
3741 sendNewConfiguration();
3742 }
3743 }
3744
3745 if ((pendingLayoutChanges & FINISH_LAYOUT_REDO_LAYOUT) != 0) {
3746 setLayoutNeeded();
3747 }
3749 // FIRST LOOP: Perform a layout, if needed.
3750 if (repeats < LAYOUT_REPEAT_THRESHOLD) {
3751 performLayout(repeats == 1, false /* updateInputWindows */);
3752 } else {
3753 Slog.w(TAG, "Layout repeat skipped after too many iterations");
3754 }
3755
3756 // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think it is animating.
3757 pendingLayoutChanges = 0;
//pendingLayoutChanges赋值,判断是否需要下一次计算
3759 Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applyPostLayoutPolicy");
3760 try {
3761 mDisplayPolicy.beginPostLayoutPolicyLw();
3762 forAllWindows(mApplyPostLayoutPolicy, true /* traverseTopToBottom */);
3763 pendingLayoutChanges |= mDisplayPolicy.finishPostLayoutPolicyLw();
3764 } finally {
3765 Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
3766 }
///
....
3767 if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats(
3768 "after finishPostLayoutPolicyLw", pendingLayoutChanges);
3769 mInsetsStateController.onPostLayout();
3770 } while (pendingLayoutChanges != 0);
.....
.....
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applyWindowSurfaceChanges");
try {
//调用 winAnimator.computeShownFrameLocked(); 计算动画变换矩阵 包括转屏,平移等动画
forAllWindows(mApplySurfaceChangesTransaction, true /* traverseTopToBottom */);
} finally {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
......
}
基于pendingLayoutChanges 这个值是否跳出循环,关注pendingLayoutChanges的赋值
frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java
private final Consumer<WindowState> mApplySurfaceChangesTransaction = w -> {
final WindowSurfacePlacer surfacePlacer = mWmService.mWindowPlacerLocked;
final boolean obscuredChanged = w.mObscured !=
mTmpApplySurfaceChangesTransactionState.obscured;
final RootWindowContainer root = mWmService.mRoot;
....
// Moved from updateWindowsAndWallpaperLocked().
if (w.mHasSurface) {
///commitFinishDrawingLocked中设置window转台为READY_TO_SHOW,
//其方法中的方法中调用WindowState.performShowLocked更新窗口绘制状态 为HAS_DRAWN
// Take care of the window being ready to display.
final boolean committed = winAnimator.commitFinishDrawingLocked();
.......
}
....
}