当前位置: 首页 > news >正文

Android14 WMS-窗口绘制之relayoutWindow流程(二)-Server端

本文接着如下文章往下讲

Android14 WMS-窗口绘制之relayoutWindow流程(一)-Client端-CSDN博客

然后就到了Server端WMS的核心实现方法relayoutWindow里29f881a37fcb498095f0b6ace978d5e4.jpg  

WindowManagerService.java - OpenGrok cross reference for /frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java

public class WindowManagerService extends IWindowManager.Stubimplements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {
...public int relayoutWindow(Session session, IWindow client, LayoutParams attrs,int requestedWidth, int requestedHeight, int viewVisibility, int flags, int seq,int lastSyncSeqId, ClientWindowFrames outFrames,MergedConfiguration outMergedConfiguration, SurfaceControl outSurfaceControl,InsetsState outInsetsState, InsetsSourceControl.Array outActiveControls,Bundle outSyncIdBundle) {

  由于此方法太长,所以分开讲述

1. 第一步

        if (outActiveControls != null) {outActiveControls.set(null);}int result = 0;boolean configChanged = false;
//获取发起者的Uid和Pidfinal int pid = Binder.getCallingPid();final int uid = Binder.getCallingUid();final long origId = Binder.clearCallingIdentity();synchronized (mGlobalLock) {
//通过IBinder client查询mWindowMap中对应的WindowState final WindowState win = windowForClientLocked(session, client, false);if (win == null) {return 0;}if (win.mRelayoutSeq < seq) {win.mRelayoutSeq = seq;} else if (win.mRelayoutSeq > seq) {return 0;}if (win.cancelAndRedraw() && win.mPrepareSyncSeqId <= lastSyncSeqId) {// The client has reported the sync draw, but we haven't finished it yet.// Don't let the client perform a non-sync draw at this time.result |= RELAYOUT_RES_CANCEL_AND_REDRAW;}
//获取window对应的DisplayContent final DisplayContent displayContent = win.getDisplayContent();
//获取window对应的DisplayPolicy final DisplayPolicy displayPolicy = displayContent.getDisplayPolicy();
//获取window对应的WindowStateAnimator WindowStateAnimator winAnimator = win.mWinAnimator;if (viewVisibility != View.GONE) {
//如果不是Gone,则更新全局变量之窗口申请的宽高 mRequestedWidth mRequestedHeight win.setRequestedSize(requestedWidth, requestedHeight);}

2. 第二步

            int attrChanges = 0;int flagChanges = 0;int privateFlagChanges = 0;
//如果窗口的属性不为空,则说明有要更新的窗口属性if (attrs != null) {
//调整窗口参数,主要是针对某些窗口类型,清理一些窗口属性参数displayPolicy.adjustWindowParamsLw(win, attrs);
...
窗口type在窗口add之后不能被改变,否则就会异常,窗口type是区分窗口层级很重要的一个东西if (win.mAttrs.type != attrs.type) {throw new IllegalArgumentException("Window type can not be changed after the window is added.");}
...
//异或^     两个位相同为0,相异为1flagChanges = win.mAttrs.flags ^ attrs.flags;privateFlagChanges = win.mAttrs.privateFlags ^ attrs.privateFlags;attrChanges = win.mAttrs.copyFrom(attrs);final boolean layoutChanged =(attrChanges & WindowManager.LayoutParams.LAYOUT_CHANGED) != 0;if (layoutChanged || (attrChanges& WindowManager.LayoutParams.SYSTEM_UI_VISIBILITY_CHANGED) != 0) {
窗口布局有变化,需要更新win.mLayoutNeeded = true;}if (layoutChanged && win.providesDisplayDecorInsets()) {configChanged = displayPolicy.updateDecorInsetsInfo();}
//看下有没有锁屏相关的flag变化if (win.mActivityRecord != null && ((flagChanges & FLAG_SHOW_WHEN_LOCKED) != 0|| (flagChanges & FLAG_DISMISS_KEYGUARD) != 0)) {win.mActivityRecord.checkKeyguardFlagsChanged();}if ((privateFlagChanges & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS) != 0) {updateNonSystemOverlayWindowsVisibilityIfNeeded(win, win.mWinAnimator.getShown());}if ((attrChanges & (WindowManager.LayoutParams.PRIVATE_FLAGS_CHANGED)) != 0) {winAnimator.setColorSpaceAgnosticLocked((win.mAttrs.privateFlags& WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC) != 0);}
...}

3. 第三步

            int attrChanges = 0;int flagChanges = 0;int privateFlagChanges = 0;
//如果窗口的属性不为空,则说明有要更新的窗口属性if (attrs != null) {
//调整窗口参数,主要是针对某些窗口类型,清理一些窗口属性参数displayPolicy.adjustWindowParamsLw(win, attrs);
...
窗口type在窗口add之后不能被改变,否则就会异常,窗口type是区分窗口层级很重要的一个东西if (win.mAttrs.type != attrs.type) {throw new IllegalArgumentException("Window type can not be changed after the window is added.");}
...
//异或^     两个位相同为0,相异为1flagChanges = win.mAttrs.flags ^ attrs.flags;privateFlagChanges = win.mAttrs.privateFlags ^ attrs.privateFlags;attrChanges = win.mAttrs.copyFrom(attrs);final boolean layoutChanged =(attrChanges & WindowManager.LayoutParams.LAYOUT_CHANGED) != 0;if (layoutChanged || (attrChanges& WindowManager.LayoutParams.SYSTEM_UI_VISIBILITY_CHANGED) != 0) {
窗口布局有变化,需要更新win.mLayoutNeeded = true;}if (layoutChanged && win.providesDisplayDecorInsets()) {configChanged = displayPolicy.updateDecorInsetsInfo();}
//看下有没有锁屏相关的flag变化if (win.mActivityRecord != null && ((flagChanges & FLAG_SHOW_WHEN_LOCKED) != 0|| (flagChanges & FLAG_DISMISS_KEYGUARD) != 0)) {win.mActivityRecord.checkKeyguardFlagsChanged();}if ((privateFlagChanges & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS) != 0) {updateNonSystemOverlayWindowsVisibilityIfNeeded(win, win.mWinAnimator.getShown());}if ((attrChanges & (WindowManager.LayoutParams.PRIVATE_FLAGS_CHANGED)) != 0) {winAnimator.setColorSpaceAgnosticLocked((win.mAttrs.privateFlags& WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC) != 0);}
...}

4. 第四步

//06-01 10:12:18.006  1890  2256 V WindowManager: Relayout Window{8d0d088 u0 
//com.android.settings/com.android.settings.homepage.SettingsHomepageActivity}: 
//viewVisibility=0 req=7104x3840 {(0,0)(fillxfill) sim={adjust=resize forwardNavigation} 
//ty=BASE_APPLICATION wanim=0x10302f2
//06-01 10:12:18.006  1890  2256 V WindowManager:   fl=LAYOUT_IN_SCREEN //LAYOUT_INSET_DECOR 
//SPLIT_TOUCH HARDWARE_ACCELERATED DRAWS_SYSTEM_BAR_BACKGROUNDS
//06-01 10:12:18.006  1890  2256 V WindowManager:   pfl=NO_MOVE_ANIMATION 
//FORCE_DRAW_STATUS_BAR_BACKGROUND HIDE_NON_SYSTEM_OVERLAY_WINDOWS USE_BLAST 
//FIT_INSETS_CONTROLLED
//06-01 10:12:18.006  1890  2256 V WindowManager:   vsysui=LIGHT_STATUS_BAR 
//LIGHT_NAVIGATION_BAR
//06-01 10:12:18.006  1890  2256 V WindowManager:   apr=LIGHT_STATUS_BARS 
//LIGHT_NAVIGATION_BARS
//06-01 10:12:18.006  1890  2256 V WindowManager:   bhv=DEFAULT
//06-01 10:12:18.006  1890  2256 V WindowManager:   fitSides=}if (DEBUG_LAYOUT) Slog.v(TAG_WM, "Relayout " + win + ": viewVisibility=" + viewVisibility+ " req=" + requestedWidth + "x" + requestedHeight + " " + win.mAttrs);if ((attrChanges & WindowManager.LayoutParams.ALPHA_CHANGED) != 0) {winAnimator.mAlpha = attrs.alpha;}
//设置窗口大小win.setWindowScale(win.mRequestedWidth, win.mRequestedHeight);if (win.mAttrs.surfaceInsets.left != 0|| win.mAttrs.surfaceInsets.top != 0|| win.mAttrs.surfaceInsets.right != 0|| win.mAttrs.surfaceInsets.bottom != 0) {winAnimator.setOpaqueLocked(false);}final int oldVisibility = win.mViewVisibility;// If the window is becoming visible, visibleOrAdding may change which may in turn// change the IME target.
//窗口由不可见/Gone变为可见final boolean becameVisible =(oldVisibility == View.INVISIBLE || oldVisibility == View.GONE)&& viewVisibility == View.VISIBLE;boolean imMayMove = (flagChanges & (FLAG_ALT_FOCUSABLE_IM | FLAG_NOT_FOCUSABLE)) != 0|| becameVisible;
//窗口焦点更新--当之前的可见性和现在不一致,并且窗口没有携带FLAG_NOT_FOCUSABLE,并且mRelayoutCalled为falseboolean focusMayChange = win.mViewVisibility != viewVisibility|| ((flagChanges & FLAG_NOT_FOCUSABLE) != 0)|| (!win.mRelayoutCalled);boolean wallpaperMayMove = win.mViewVisibility != viewVisibility&& win.hasWallpaper();wallpaperMayMove |= (flagChanges & FLAG_SHOW_WALLPAPER) != 0;if ((flagChanges & FLAG_SECURE) != 0 && winAnimator.mSurfaceController != null) {winAnimator.mSurfaceController.setSecure(win.isSecureLocked());}final boolean wasVisible = win.isVisible();win.mRelayoutCalled = true;win.mInRelayout = true;
//设置窗口可见性为申请的可见性,可见则viewVisibility=0win.setViewVisibility(viewVisibility);ProtoLog.i(WM_DEBUG_SCREEN_ON,"Relayout %s: oldVis=%d newVis=%d. %s", win, oldVisibility,viewVisibility, new RuntimeException().fillInStackTrace());
//06-01 10:12:18.008  1890  2256 W WindowManager: setLayoutNeeded: 
//callers=com.android.server.wm.WindowState.setDisplayLayoutNeeded:2671 
//com.android.server.wm.WindowManagerService.relayoutWindow:2419 
//com.android.server.wm.Session.relayout:249 win.setDisplayLayoutNeeded();win.mGivenInsetsPending = (flags & WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;
 

viewVisibility代表当前View的可见性

mViewVisibilityVlaue含义
VISIBLE0x00000000

这个视图可见

与#setVisibility和#attr_android:visibility" android:visibility}一起使用。

INVISIBLE0x00000004

这个视图不可见

与#setVisibility和#attr_android:visibility" android:visibility}一起使用。

GONE0x00000008

这个视图是不可见的,它不占用任何空间进行布局

与#setVisibility和#attr_android:visibility" android:visibility}一起使用。

5. 第五步 创建Surface图层流程

            // We should only relayout if the view is visible, it is a starting window, or the// associated appToken is not hidden.
//只有当视图可见、并且它是STARTING窗口或关联的 appToken 未隐藏时,我们才应该重新布局。final boolean shouldRelayout = viewVisibility == View.VISIBLE &&(win.mActivityRecord == null || win.mAttrs.type == TYPE_APPLICATION_STARTING|| win.mActivityRecord.isClientVisible());// If we are not currently running the exit animation, we need to see about starting// one.// This must be called before the call to performSurfacePlacement.
//如果我们当前没有运行退出动画,满足下列条件,则需执行退出动画if (!shouldRelayout && winAnimator.hasSurface() && !win.mAnimatingExit) {if (DEBUG_VISIBILITY) {
//06-01 10:12:14.228  1890  2256 I WindowManager: Relayout invis Window{8c33950 u0 
//NotificationShade}: mAnimatingExit=falseSlog.i(TAG_WM,"Relayout invis " + win + ": mAnimatingExit=" + win.mAnimatingExit);}result |= RELAYOUT_RES_SURFACE_CHANGED;// When FLAG_SHOW_WALLPAPER flag is removed from a window, we usually set a flag// in DC#pendingLayoutChanges and update the wallpaper target later.// However it's possible that FLAG_SHOW_WALLPAPER flag is removed from a window// when the window is about to exit, so we update the wallpaper target// immediately here. Otherwise this window will be stuck in exiting and its// surface remains on the screen.// TODO(b/189856716): Allow destroying surface even if it belongs to the//  keyguard target.if (wallpaperMayMove) {displayContent.mWallpaperController.adjustWallpaperWindows();}
//执行窗口退出动画tryStartExitingAnimation(win, winAnimator);}// Create surfaceControl before surface placement otherwise layout will be skipped// (because WS.isGoneForLayout() is true when there is no surface.
//outSurfaceControl是client端传入的,在ViewRootImpl全局变量中就实例化好了
//http://aospxref.com/android-14.0.0_r2/xref/frameworks/base/core/java/android/view/ViewRootImpl.java#708
//private final SurfaceControl mSurfaceControl = new SurfaceControl();
//所以这个不会为空if (shouldRelayout && outSurfaceControl != null) {try {
//创建图层result = createSurfaceControl(outSurfaceControl, result, win, winAnimator);} catch (Exception e) {displayContent.getInputMonitor().updateInputWindowsLw(true /*force*/);ProtoLog.w(WM_ERROR,"Exception thrown when creating surface for client %s (%s). %s",client, win.mAttrs.getTitle(), e);Binder.restoreCallingIdentity(origId);return 0;}}
 

5.1 WindowManagerService#createSurfaceControl

WindowManagerService.java - OpenGrok cross reference for /frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java

    private int createSurfaceControl(SurfaceControl outSurfaceControl, int result,WindowState win, WindowStateAnimator winAnimator) {if (!win.mHasSurface) {result |= RELAYOUT_RES_SURFACE_CHANGED;}WindowSurfaceController surfaceController;try {Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "createSurfaceControl");
//创建window对应的surface图层surfaceController = winAnimator.createSurfaceLocked();
...if (surfaceController != null) {surfaceController.getSurfaceControl(outSurfaceControl);ProtoLog.i(WM_SHOW_TRANSACTIONS, "OUT SURFACE %s: copied", outSurfaceControl);} else {
...}

 5.2  WindowStateAnimator#createSurfaceLocked

WindowStateAnimator.java - OpenGrok cross reference for /frameworks/base/services/core/java/com/android/server/wm/WindowStateAnimator.java

    WindowSurfaceController createSurfaceLocked() {final WindowState w = mWin;if (mSurfaceController != null) {return mSurfaceController;}
//设置是否有Surface标志位为falsew.setHasSurface(false);ProtoLog.i(WM_DEBUG_ANIM, "createSurface %s: mDrawState=DRAW_PENDING", this);
//重置图层绘制状态resetDrawState();
//要开始绘制图层了,要先freeze(冻住)住屏幕,等待绘制完成再Unfreeze,这里有个超时机制,即
//冻住屏幕有个最大时间WINDOW_FREEZE_TIMEOUT_DURATION--2000msmService.makeWindowFreezingScreenIfNeededLocked(w);int flags = SurfaceControl.HIDDEN;final WindowManager.LayoutParams attrs = w.mAttrs;
//如果window是加密窗口,则添加此flagif (w.isSecureLocked()) {flags |= SurfaceControl.SECURE;}if ((mWin.mAttrs.privateFlags & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0) {flags |= SurfaceControl.SKIP_SCREENSHOT;}
//06-01 10:12:18.009  1890  2256 V WindowManager: Creating surface in session 
//android.view.SurfaceSession@fcb7984 window WindowStateAnimator{31728a0 
//com.android.settings/com.android.settings.homepage.SettingsHomepageActivity} format=-1 
//flags=4if (DEBUG_VISIBILITY) {Slog.v(TAG, "Creating surface in session "+ mSession.mSurfaceSession + " window " + this+ " format=" + attrs.format + " flags=" + flags);}// Set up surface control with initial size.try {// This can be removed once we move all Buffer Layers to use BLAST.final boolean isHwAccelerated = (attrs.flags & FLAG_HARDWARE_ACCELERATED) != 0;final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : attrs.format;
//创建图层----创建WindowSurfaceController,主要是管理图层的,可设置图层位置,大小,是否可见等 mSurfaceController = new WindowSurfaceController(attrs.getTitle().toString(), format,flags, this, attrs.type);
//将 Surface 设置为与颜色空间无关。mSurfaceController.setColorSpaceAgnostic(w.getPendingTransaction(),(attrs.privateFlags & LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC) != 0);
//图层创建好了,更新是否有Surface的标志位为truew.setHasSurface(true);
...
//06-01 10:12:18.015  1890  2256 V WindowManager: Got surface: 
//Surface(name=com.android.settings/com.android.settings.homepage.SettingsHomepageActivit//y)@0xafd3c59, set left=0 top=0if (DEBUG) {Slog.v(TAG, "Got surface: " + mSurfaceController+ ", set left=" + w.getFrame().left + " top=" + w.getFrame().top);}
...mLastHidden = true;
//06-01 10:12:18.015  1890  2256 V WindowManager: Created surface 
//WindowStateAnimator{31728a0 
//com.android.settings/com.android.settings.homepage.SettingsHomepageActivity}if (DEBUG) Slog.v(TAG, "Created surface " + this);return mSurfaceController;}

  5.3 WindowSurfaceController之创建图层

    WindowSurfaceController(String name, int format, int flags, WindowStateAnimator animator,int windowType) {mAnimator = animator;title = name;mService = animator.mService;final WindowState win = animator.mWin;mWindowType = windowType;mWindowSession = win.mSession;Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "new SurfaceControl");
//创建图层final SurfaceControl.Builder b = win.makeSurface().setParent(win.getSurfaceControl()).setName(name).setFormat(format).setFlags(flags).setMetadata(METADATA_WINDOW_TYPE, windowType).setMetadata(METADATA_OWNER_UID, mWindowSession.mUid).setMetadata(METADATA_OWNER_PID, mWindowSession.mPid).setCallsite("WindowSurfaceController");final boolean useBLAST = mService.mUseBLAST && ((win.getAttrs().privateFlags& WindowManager.LayoutParams.PRIVATE_FLAG_USE_BLAST) != 0);if (useBLAST) {b.setBLASTLayer();}mSurfaceControl = b.build();Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);}
-------------------------------------------------------------------
//http://aospxref.com/android-14.0.0_r2/xref/frameworks/base/core/java/android/view/SurfaceControl.java#857public static class Builder {/*** Begin building a SurfaceControl.*/public Builder() {}/*** Construct a new {@link SurfaceControl} with the set parameters. The builder* remains valid.*/@NonNullpublic SurfaceControl build() {if (mWidth < 0 || mHeight < 0) {throw new IllegalStateException("width and height must be positive or unset");}if ((mWidth > 0 || mHeight > 0) && (isEffectLayer() || isContainerLayer())) {throw new IllegalStateException("Only buffer layers can set a valid buffer size.");}if (mName == null) {Log.w(TAG, "Missing name for SurfaceControl", new Throwable());}if ((mFlags & FX_SURFACE_MASK) == FX_SURFACE_NORMAL) {setBLASTLayer();}return new SurfaceControl(mSession, mName, mWidth, mHeight, mFormat, mFlags, mParent, mMetadata,mLocalOwnerView, mCallsite);}---------------------------------------------------------private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags,SurfaceControl parent, SparseIntArray metadata, WeakReference<View> localOwnerView,String callsite)throws OutOfResourcesException, IllegalArgumentException {if (name == null) {throw new IllegalArgumentException("name must not be null");}mName = name;mWidth = w;mHeight = h;mLocalOwnerView = localOwnerView;Parcel metaParcel = Parcel.obtain();long nativeObject = 0;try {if (metadata != null && metadata.size() > 0) {metaParcel.writeInt(metadata.size());for (int i = 0; i < metadata.size(); ++i) {metaParcel.writeInt(metadata.keyAt(i));metaParcel.writeByteArray(ByteBuffer.allocate(4).order(ByteOrder.nativeOrder()).putInt(metadata.valueAt(i)).array());}metaParcel.setDataPosition(0);}nativeObject = nativeCreate(session, name, w, h, format, flags,parent != null ? parent.mNativeObject : 0, metaParcel);} finally {metaParcel.recycle();}if (nativeObject == 0) {throw new OutOfResourcesException("Couldn't allocate SurfaceControl native object");}assignNativeObject(nativeObject, callsite);}

6. 第六步 刷新界面和更新焦点

// We may be deferring layout passes at the moment, but since the client is interested// in the new out values right now we need to force a layout.mWindowPlacerLocked.performSurfacePlacement(true /* force */);

6.1 WindowSurfacePlacer#performSurfacePlacement 刷新界面和更新焦点

performSurfacePlacement 看方法名,perform surface place,即负责所有窗口的Surface的摆放工作,如何显示位置,大小等等,是WMS中的核心方法

90e8fa75df9f4c1bb4ed707d707d3fe1.jpg

下面这些流程的流程图如上

    final void performSurfacePlacement(boolean force) {if (mDeferDepth > 0 && !force) {mDeferredRequests++;return;}
//最大执行6次循环int loopCount = 6;do {mTraversalScheduled = false;performSurfacePlacementLoop();mService.mAnimationHandler.removeCallbacks(mPerformSurfacePlacement);loopCount--;} while (mTraversalScheduled && loopCount > 0);mService.mRoot.mWallpaperActionPending = false;}private void performSurfacePlacementLoop() {
//此方法下面已经有地方将mInLayout置为true,说明已经正在执行performSurfacePlacementLoop方法了if (mInLayout) {
...return;}// TODO(multi-display):final DisplayContent defaultDisplay = mService.getDefaultDisplayContentLocked();
//mWaitingForConfig作用是Used to gate application window layout until we have sent the complete configuration.
//当没有完成configuration change的时候,无需做relayout,直到configuration change完成if (defaultDisplay.mWaitingForConfig) {// Our configuration has changed (most likely rotation), but we// don't yet have the complete configuration to report to// applications.  Don't do any window layout until we have it.return;}
//屏幕没准备好,直接返回if (!mService.mDisplayReady) {// Not yet initialized, nothing to do.return;}
//对应第一行标志位,表示正在layoutmInLayout = true;
//内存不足时,强制清理mForceRemoves集合,释放内存if (!mService.mForceRemoves.isEmpty()) {// Wait a little bit for things to settle down, and off we go.while (!mService.mForceRemoves.isEmpty()) {final WindowState ws = mService.mForceRemoves.remove(0);Slog.i(TAG, "Force removing: " + ws);ws.removeImmediately();}Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");Object tmp = new Object();synchronized (tmp) {try {tmp.wait(250);} catch (InterruptedException e) {}}}try {
//核心的一步mService.mRoot.performSurfacePlacement();
//标志位置为false,走完上面这步,layout就完成了mInLayout = false;if (mService.mRoot.isLayoutNeeded()) {
//需要layout,并且count<6if (++mLayoutRepeatCount < 6) {requestTraversal();} else {
...}

6.2 RootWindowContainer#performSurfacePlacement

RootWindowContainer.java - OpenGrok cross reference for /frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java

    void performSurfacePlacement() {Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "performSurfacePlacement");try {performSurfacePlacementNoTrace();} finally {Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);}}

 6.3 RootWindowContainer#performSurfacePlacementNoTrace - part1

这个方法也很长,当窗口的某些东西改变的时候,就会走到这里,由于太长,我们分开去讲

    void performSurfacePlacementNoTrace() {if (DEBUG_WINDOW_TRACE) {
//06-01 10:12:18.016  1890  2256 V WindowManager: performSurfacePlacementInner: entry. 
//Called by com.android.server.wm.RootWindowContainer.performSurfacePlacement:765 
//com.android.server.wm.WindowSurfacePlacer.performSurfacePlacementLoop:177 
//com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement:126 Slog.v(TAG, "performSurfacePlacementInner: entry. Called by "+ Debug.getCallers(3));}int i;if (mWmService.mFocusMayChange) {mWmService.mFocusMayChange = false;
//更新焦点窗口mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);}mScreenBrightnessOverride = PowerManager.BRIGHTNESS_INVALID_FLOAT;mUserActivityTimeout = -1;mObscureApplicationContentOnSecondaryDisplays = false;mSustainedPerformanceModeCurrent = false;mWmService.mTransactionSequence++;// TODO(multi-display): recents animation & wallpaper need support multi-display.final DisplayContent defaultDisplay = mWmService.getDefaultDisplayContentLocked();
//获取WindowSurfacePlacer,这个类专门用于摆放windows和他们的surfaces,
//全系统只有一个实例,在WMS实例化中进行的final WindowSurfacePlacer surfacePlacer = mWmService.mWindowPlacerLocked;
//要开始进行过渡动画了if (SHOW_LIGHT_TRANSACTIONS) {Slog.i(TAG,">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");}Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applySurfaceChanges");
//设置surface参数,start a transaction,对一组 SurfaceControl 的原子更改。
//即通过SurfaceControl来通知native开始一个TransactionmWmService.openSurfaceTransaction();try {
//执行Transaction
//下面详细解释这里applySurfaceChangesTransaction();} catch (RuntimeException e) {Slog.wtf(TAG, "Unhandled exception in Window Manager", e);} finally {
//close surface TransactionmWmService.closeSurfaceTransaction("performLayoutAndPlaceSurfaces");Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);if (SHOW_LIGHT_TRANSACTIONS) {Slog.i(TAG,"<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");}}
...
剩下的分另一半说
6.3.1 RootWindowContainer#applySurfaceChangesTransaction

RootWindowContainer.java - OpenGrok cross reference for /frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java

    private void applySurfaceChangesTransaction() {// TODO(multi-display): Support these features on secondary screens.final DisplayContent defaultDc = mDefaultDisplay;final DisplayInfo defaultInfo = defaultDc.getDisplayInfo();final int defaultDw = defaultInfo.logicalWidth;final int defaultDh = defaultInfo.logicalHeight;final SurfaceControl.Transaction t = defaultDc.getSyncTransaction();
...
//mChildren为“List of children for this window container”,
//也就是这个WindowContainer的一系列子windowContainer的集合final int count = mChildren.size();
//循环遍历for (int j = 0; j < count; ++j) {
//获取到这个WindowContainer对应的DisplayContent final DisplayContent dc = mChildren.get(j);
//对这个DisplayContent进行applySurfaceChangesTransactiondc.applySurfaceChangesTransaction();}// Give the display manager a chance to adjust properties like display rotation if it needs// to.mWmService.mDisplayManagerInternal.performTraversal(t);if (t != defaultDc.mSyncTransaction) {SurfaceControl.mergeToGlobalTransaction(t);}}

借用一张图来表示mChildren,mChildren里保存的都是WidowContainer,并且这些WidowContainer按Z值排序,Z值越大越靠前

WindowContainer.java - OpenGrok cross reference for /frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java 

"List of children for this window container. List is in z-order as the children appear on screen with the top-most window container at the tail of the list."

  protected final WindowList<E> mChildren = new WindowList<E>();

05342f3048dc4ea3adefed42dde7e65c.png

 6.3.2 DisplayContent#applySurfaceChangesTransaction

DisplayContent.java - OpenGrok cross reference for /frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java

    void applySurfaceChangesTransaction() {final WindowSurfacePlacer surfacePlacer = mWmService.mWindowPlacerLocked;beginHoldScreenUpdate();mTmpUpdateAllDrawn.clear();
...// Perform a layout, if needed.performLayout(true /* initial */, false /* updateInputWindows */);pendingLayoutChanges = 0;Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applyPostLayoutPolicy");try {mDisplayPolicy.beginPostLayoutPolicyLw();
//遍历windows   执行mApplyPostLayoutPolicyforAllWindows(mApplyPostLayoutPolicy, true /* traverseTopToBottom */);mDisplayPolicy.finishPostLayoutPolicyLw();} finally {Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);}mInsetsStateController.onPostLayout();mTmpApplySurfaceChangesTransactionState.reset();Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applyWindowSurfaceChanges");try {
//遍历windows
//执行mApplySurfaceChangesTransactionforAllWindows(mApplySurfaceChangesTransaction, true /* traverseTopToBottom */);} finally {Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);}prepareSurfaces();
...finishHoldScreenUpdate();}
 6.3.3 DisplayContent#performLayout

DisplayContent.java - OpenGrok cross reference for /frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java

    void performLayout(boolean initial, boolean updateInputWindows) {Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "performLayout");try {performLayoutNoTrace(initial, updateInputWindows);} finally {Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);}}private void performLayoutNoTrace(boolean initial, boolean updateInputWindows) {if (!isLayoutNeeded()) {return;}
//将mLayoutNeeded = false;
//会打印堆栈:06-01 10:12:18.016  1890  2256 W WindowManager: clearLayoutNeeded: 
//callers=com.android.server.wm.DisplayContent.performLayoutNoTrace:5051 
//com.android.server.wm.DisplayContent.performLayout:5041 
//com.android.server.wm.DisplayContent.applySurfaceChangesTransaction:4963 clearLayoutNeeded();if (DEBUG_LAYOUT) {
//06-01 10:12:18.016  1890  2256 V WindowManager: performLayout: dw=3840 dh=7104 Slog.v(TAG, "-------------------------------------");Slog.v(TAG, "performLayout: dw=" + mDisplayInfo.logicalWidth+ " dh=" + mDisplayInfo.logicalHeight);}int seq = mLayoutSeq + 1;if (seq < 0) seq = 0;mLayoutSeq = seq;mTmpInitial = initial;// First perform layout of any root windows (not attached to another window).
//首先给所有windows执行layout,mPerformLayout稍后解释forAllWindows(mPerformLayout, true /* traverseTopToBottom */);// Now perform layout of attached windows, which usually depend on the position of the// window they are attached to. XXX does not deal with windows that are attached to windows// that are themselves attached.
//给所有attached windows执行layout操作forAllWindows(mPerformLayoutAttached, true /* traverseTopToBottom */);// Window frames may have changed. Tell the input dispatcher about it.
//更新input windowmInputMonitor.setUpdateInputWindowsNeededLw();if (updateInputWindows) {mInputMonitor.updateInputWindowsLw(false /*force*/);}}
DisplayContent#  mPerformLayout赋值如下:

DisplayContent.java - OpenGrok cross reference for /frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java

    private final Consumer<WindowState> mPerformLayout = w -> {if (w.mLayoutAttached) {return;}// Don't do layout of a window if it is not visible, or soon won't be visible, to avoid// wasting time and funky changes while a window is animating away.final boolean gone = w.isGoneForLayout();if (DEBUG_LAYOUT) {Slog.v(TAG, "1ST PASS " + w + ": gone=" + gone + " mHaveFrame=" + w.mHaveFrame+ " config reported=" + w.isLastConfigReportedToClient());final ActivityRecord activity = w.mActivityRecord;if (gone) Slog.v(TAG, "  GONE: mViewVisibility=" + w.mViewVisibility+ " mRelayoutCalled=" + w.mRelayoutCalled + " visible=" + w.mToken.isVisible()+ " visibleRequested=" + (activity != null && activity.isVisibleRequested())+ " parentHidden=" + w.isParentWindowHidden());else Slog.v(TAG, "  VIS: mViewVisibility=" + w.mViewVisibility+ " mRelayoutCalled=" + w.mRelayoutCalled + " visible=" + w.mToken.isVisible()+ " visibleRequested=" + (activity != null && activity.isVisibleRequested())+ " parentHidden=" + w.isParentWindowHidden());}// If this view is GONE, then skip it -- keep the current frame, and let the caller know// so they can ignore it if they want.  (We do the normal layout for INVISIBLE windows,// since that means "perform layout as normal, just don't display").if (!gone || !w.mHaveFrame || w.mLayoutNeeded) {if (mTmpInitial) {w.resetContentChanged();}w.mSurfacePlacementNeeded = true;w.mLayoutNeeded = false;final boolean firstLayout = !w.isLaidOut();
// Called for each window attached to the window manager as layout is proceeding
//在布局进行时调用附加到窗口管理器的每个窗口getDisplayPolicy().layoutWindowLw(w, null, mDisplayFrames);w.mLayoutSeq = mLayoutSeq;// If this is the first layout, we need to initialize the last frames and inset values,// as otherwise we'd immediately cause an unnecessary resize.if (firstLayout) {// The client may compute its actual requested size according to the first layout,// so we still request the window to resize if the current frame is empty.if (!w.getFrame().isEmpty()) {w.updateLastFrames();}w.onResizeHandled();}if (DEBUG_LAYOUT) Slog.v(TAG, "  LAYOUT: mFrame=" + w.getFrame()+ " mParentFrame=" + w.getParentFrame()+ " mDisplayFrame=" + w.getDisplayFrame());}};
DisplayPolicy#layoutWindowLw
    public void layoutWindowLw(WindowState win, WindowState attached, DisplayFrames displayFrames) {
...mWindowLayout.computeFrames(attrs, win.getInsetsState(), displayFrames.mDisplayCutoutSafe,win.getBounds(), win.getWindowingMode(), requestedWidth, requestedHeight,win.getRequestedVisibleTypes(), win.mGlobalScale, sTmpClientFrames);win.setFrames(sTmpClientFrames, win.mRequestedWidth, win.mRequestedHeight);}
DisplayContent#  ​​​​​​​mApplyPostLayoutPolicy赋值如下:
    private final Consumer<WindowState> mApplyPostLayoutPolicy =w -> getDisplayPolicy().applyPostLayoutPolicyLw(w, w.mAttrs, w.getParentWindow(), mImeLayeringTarget);

DisplayPolicy.java - OpenGrok cross reference for /frameworks/base/services/core/java/com/android/server/wm/DisplayPolicy.java

    /*** Called following layout of all window to apply policy to each window.** @param win The window being positioned.* @param attrs The LayoutParams of the window.* @param attached For sub-windows, the window it is attached to. Otherwise null.*/public void applyPostLayoutPolicyLw(WindowState win, WindowManager.LayoutParams attrs, WindowState attached, WindowState imeTarget) {
 DisplayContent#  ​​​​​​​mApplySurfaceChangesTransaction赋值如下
    private final Consumer<WindowState> mApplySurfaceChangesTransaction = w -> {final WindowSurfacePlacer surfacePlacer = mWmService.mWindowPlacerLocked;final boolean obscuredChanged = w.mObscured !=mTmpApplySurfaceChangesTransactionState.obscured;final RootWindowContainer root = mWmService.mRoot;// Update effect.w.mObscured = mTmpApplySurfaceChangesTransactionState.obscured;if (!mTmpApplySurfaceChangesTransactionState.obscured) {final boolean isDisplayed = w.isDisplayed();if (isDisplayed && w.isObscuringDisplay()) {// This window completely covers everything behind it, so we want to leave all// of them as undimmed (for performance reasons).mObscuringWindow = w;mTmpApplySurfaceChangesTransactionState.obscured = true;}final boolean displayHasContent = root.handleNotObscuredLocked(w,mTmpApplySurfaceChangesTransactionState.obscured,mTmpApplySurfaceChangesTransactionState.syswin);if (!mTmpApplySurfaceChangesTransactionState.displayHasContent&& !getDisplayPolicy().isWindowExcludedFromContent(w)) {mTmpApplySurfaceChangesTransactionState.displayHasContent |= displayHasContent;}if (w.mHasSurface && isDisplayed) {if ((w.mAttrs.flags & FLAG_KEEP_SCREEN_ON) != 0) {mTmpHoldScreenWindow = w;} else if (w == mLastWakeLockHoldingWindow) {ProtoLog.d(WM_DEBUG_KEEP_SCREEN_ON,"handleNotObscuredLocked: %s was holding screen wakelock but no longer "+ "has FLAG_KEEP_SCREEN_ON!!! called by%s",w, Debug.getCallers(10));}final int type = w.mAttrs.type;if (type == TYPE_SYSTEM_DIALOG|| type == TYPE_SYSTEM_ERROR|| (type == TYPE_NOTIFICATION_SHADE&&  mWmService.mPolicy.isKeyguardShowing())) {mTmpApplySurfaceChangesTransactionState.syswin = true;}if (mTmpApplySurfaceChangesTransactionState.preferredRefreshRate == 0&& w.mAttrs.preferredRefreshRate != 0) {mTmpApplySurfaceChangesTransactionState.preferredRefreshRate= w.mAttrs.preferredRefreshRate;}mTmpApplySurfaceChangesTransactionState.preferMinimalPostProcessing|= w.mAttrs.preferMinimalPostProcessing;mTmpApplySurfaceChangesTransactionState.disableHdrConversion|= !(w.mAttrs.isHdrConversionEnabled());final int preferredModeId = getDisplayPolicy().getRefreshRatePolicy().getPreferredModeId(w);if (w.getWindowingMode() != WINDOWING_MODE_PINNED&& mTmpApplySurfaceChangesTransactionState.preferredModeId == 0&& preferredModeId != 0) {mTmpApplySurfaceChangesTransactionState.preferredModeId = preferredModeId;}final float preferredMinRefreshRate = getDisplayPolicy().getRefreshRatePolicy().getPreferredMinRefreshRate(w);if (mTmpApplySurfaceChangesTransactionState.preferredMinRefreshRate == 0&& preferredMinRefreshRate != 0) {mTmpApplySurfaceChangesTransactionState.preferredMinRefreshRate =preferredMinRefreshRate;}final float preferredMaxRefreshRate = getDisplayPolicy().getRefreshRatePolicy().getPreferredMaxRefreshRate(w);if (mTmpApplySurfaceChangesTransactionState.preferredMaxRefreshRate == 0&& preferredMaxRefreshRate != 0) {mTmpApplySurfaceChangesTransactionState.preferredMaxRefreshRate =preferredMaxRefreshRate;}}}if (obscuredChanged && w.isVisible() && mWallpaperController.isWallpaperTarget(w)) {// This is the wallpaper target and its obscured state changed... make sure the// current wallpaper's visibility has been updated accordingly.mWallpaperController.updateWallpaperVisibility();}w.handleWindowMovedIfNeeded();final WindowStateAnimator winAnimator = w.mWinAnimator;//Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");w.resetContentChanged();// Moved from updateWindowsAndWallpaperLocked().if (w.mHasSurface) {// Take care of the window being ready to display.final boolean committed = winAnimator.commitFinishDrawingLocked();if (isDefaultDisplay && committed) {if (w.hasWallpaper()) {ProtoLog.v(WM_DEBUG_WALLPAPER,"First draw done in potential wallpaper target %s", w);mWallpaperMayChange = true;pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;if (DEBUG_LAYOUT_REPEATS) {surfacePlacer.debugLayoutRepeats("wallpaper and commitFinishDrawingLocked true",pendingLayoutChanges);}}}}final ActivityRecord activity = w.mActivityRecord;if (activity != null && activity.isVisibleRequested()) {activity.updateLetterboxSurface(w);final boolean updateAllDrawn = activity.updateDrawnWindowStates(w);if (updateAllDrawn && !mTmpUpdateAllDrawn.contains(activity)) {mTmpUpdateAllDrawn.add(activity);}}w.updateResizingWindowIfNeeded();};

在这个过程中会通过commitFinishDrawingLocked去检查当前窗口的mDrawState情况。Surface的mDrawState的绘制状态是由ViewRootImpl通过Session调用到WMS端,然后在WMS端设置的。

当此window窗口的mDrawState变化状态从NO_SURFACE -> DRAW_PENDING -> COMMIT_DRAW_PENDING  -> HAS_DRAWN-> READY_TO_SHOW,然后才会将图层置为可见状态,设置为可见的log如下:

05-24 08:48:44.864  1904  2924 V WindowManager: Created surface WindowStateAnimator{69dac93 Splash Screen com.android.settings}
//mDrawState由于没开始绘制,所以置为DRAW_PENDING
05-24 08:48:44.869  1904  2924 I WindowManager: commitFinishDrawingLocked: Window{f4e70cd u0 Splash Screen com.android.settings} cur mDrawState=DRAW_PENDING
//ViewRootImpl端通知WMS已经绘制完成
05-24 08:48:44.901  1904  2924 V WindowManager: IWindow finishDrawing called for android.view.IWindow$Stub$Proxy@f5e4cc9
//由于已绘制完成,所以绘制状态切换成COMMIT_DRAW_PENDING,
05-24 08:48:44.905  1904  1973 I WindowManager: commitFinishDrawingLocked: Window{f4e70cd u0 Splash Screen com.android.settings} cur mDrawState=COMMIT_DRAW_PENDING
//这时候会调用WindowState#performShowLocked看能否显示
//但由于readyForDisplay为false,所以不会显示图层,会直接return
05-24 08:48:44.905  1904  1973 V WindowManager: performShow on Window{f4e70cd u0 Splash Screen com.android.settings}: mDrawState=READY_TO_SHOW readyForDisplay=false starting=true during animation: policyVis=true parentHidden=false tok.visibleRequested=false tok.visible=false animating=false tok animating=false Callers=com.android.server.wm.WindowState.performShowLocked:4372 com.android.server.wm.WindowStateAnimator.commitFinishDrawingLocked:256 com.android.server.wm.DisplayContent.lambda$new$8:1082 com.android.server.wm.DisplayContent.$r8$lambda$NJwM1ysKPNyOazqyI2QXlp2I4yA:0 
//绘制状态切为READY_TO_SHOW
05-24 08:48:45.023  1904  2924 I WindowManager: commitFinishDrawingLocked: Window{f4e70cd u0 Splash Screen com.android.settings} cur mDrawState=READY_TO_SHOW
//和上面一样readyForDisplay为false,无法显示图层
05-24 08:48:45.023  1904  2924 V WindowManager: performShow on Window{f4e70cd u0 Splash Screen com.android.settings}: mDrawState=READY_TO_SHOW readyForDisplay=false starting=true during animation: policyVis=true parentHidden=false tok.visibleRequested=true tok.visible=false animating=false tok animating=false Callers=com.android.server.wm.WindowState.performShowLocked:4372 com.android.server.wm.WindowStateAnimator.commitFinishDrawingLocked:256 com.android.server.wm.DisplayContent.lambda$new$8:1082 
com.android.server.wm.DisplayContent.$r8$lambda$NJwM1ysKPNyOazqyI2QXlp2I4yA:0 
//由于OPEN/CLOSE TRANSACTION处于一个循环中,所以会循环执行commitFinishDrawingLocked
05-24 08:48:45.024  1904  2924 I WindowManager: commitFinishDrawingLocked: Window{f4e70cd u0 Splash Screen com.android.settings} cur mDrawState=READY_TO_SHOW
//readyForDisplay置为true了,且已经绘制完成等待显示,所以此时可以显示图层了
05-24 08:48:45.024  1904  2924 V WindowManager: performShow on Window{f4e70cd u0 Splash Screen com.android.settings}: mDrawState=READY_TO_SHOW readyForDisplay=true starting=true during animation: policyVis=true parentHidden=false tok.visibleRequested=true tok.visible=true animating=false tok animating=false Callers=com.android.server.wm.WindowState.performShowLocked:4372 com.android.server.wm.WindowStateAnimator.commitFinishDrawingLocked:256 com.android.server.wm.WindowState.commitFinishDrawing:4353 com.android.server.wm.ActivityRecord.commitFinishDrawing:5720 
//显示图层
05-24 08:48:45.024  1904  2924 V WindowManager: Showing Window{f4e70cd u0 Splash Screen com.android.settings}: mDrawState=READY_TO_SHOW readyForDisplay=true starting=true during animation: policyVis=true parentHidden=false tok.visibleRequested=true tok.visible=true animating=false tok animating=false Callers=com.android.server.wm.WindowState.performShowLocked:4387 com.android.server.wm.WindowStateAnimator.commitFinishDrawingLocked:256 com.android.server.wm.WindowState.commitFinishDrawing:4353 com.android.server.wm.ActivityRecord.commitFinishDrawing:5720 
//显示Surface
05-24 08:48:45.024  1904  2924 V WindowManager: Showing Surface(name=Splash Screen com.android.settings)/@0x86974d0 during relayout
//mDrawState=HAS_DRAWN
05-24 08:48:45.690  1904  2924 I WindowManager: commitFinishDrawingLocked: Window{f4e70cd u0 Splash Screen com.android.settings} cur mDrawState=HAS_DRAWN
05-24 08:48:45.923  1904  2924 D logtag: Changing focus from Window{5a07e7f u0 NotificationShade} to null displayId=0
05-24 08:48:45.989  1904  2924 V WindowManager: Creating surface in session android.view.SurfaceSession@9763a38 window WindowStateAnimator{a0a5e3a com.android.settings/com.android.settings.homepage.SettingsHomepageActivity} format=-1 flags=4
05-24 08:48:45.995  1904  2924 V WindowManager: Got surface: Surface(name=com.android.settings/com.android.settings.homepage.SettingsHomepageActivity)/@0x9fbfaeb, set left=0 top=0
05-24 08:48:45.997  1904  2924 I WindowManager: commitFinishDrawingLocked: Window{f4e70cd u0 Splash Screen com.android.settings} cur mDrawState=HAS_DRAWN
05-24 08:48:45.999  1904  2924 D logtag: Changing focus from null to Window{f5859ad u0 com.android.settings/com.android.settings.homepage.SettingsHomepageActivity} displayId=0

 6.4 WindowManagerService#updateFocusedWindowLocked- part2

        if (mWmService.mFocusMayChange) {mWmService.mFocusMayChange = false;mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,false /*updateInputWindows*/);}

updateFocusedWindowLocked这个方法也是很重要的,用于更新窗口焦点,窗口焦点为null时,是无法接收输入事件的,只有窗口焦点不为空,并且点击输入焦点所在的窗口,才能接收到输入事件,所以窗口焦点尤为重要。input ANR 也是与此息息相关。

RootWindowContainer#updateFocusedWindowLocked
    boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {mTopFocusedAppByProcess.clear();boolean changed = false;int topFocusedDisplayId = INVALID_DISPLAY;// Go through the children in z-order starting at the top-mostfor (int i = mChildren.size() - 1; i >= 0; --i) {final DisplayContent dc = mChildren.get(i);changed |= dc.updateFocusedWindowLocked(mode, updateInputWindows, topFocusedDisplayId);
...}
DisplayContent# updateFocusedWindowLocked
    boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows,int topFocusedDisplayId) {
...
//计算新焦点窗口是哪个WindowState newFocus = findFocusedWindowIfNeeded(topFocusedDisplayId);if (mCurrentFocus == newFocus) {return false;}
...
//焦点窗口切换ProtoLog.d(WM_DEBUG_FOCUS_LIGHT, "Changing focus from %s to %s displayId=%d Callers=%s",mCurrentFocus, newFocus, getDisplayId(), Debug.getCallers(4));
...
//为输入法更新输入窗口adjustForImeIfNeeded();
...}

 6.5 RootWindowContainer#performSurfacePlacementNoTrace - part3

//如果屏幕有旋转操作,并且已经完成,此时则停止freeze住屏幕if (mOrientationChangeComplete) {if (mWmService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {mWmService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;mWmService.mLastFinishedFreezeSource = mLastWindowFreezeSource;mWmService.mH.removeMessages(WINDOW_FREEZE_TIMEOUT);}mWmService.stopFreezingDisplayLocked();}
//销毁mDestroySurface中的Surface// Destroy the surface of any windows that are no longer visible.i = mWmService.mDestroySurface.size();if (i > 0) {do {i--;WindowState win = mWmService.mDestroySurface.get(i);win.mDestroying = false;final DisplayContent displayContent = win.getDisplayContent();if (displayContent.mInputMethodWindow == win) {displayContent.setInputMethodWindowLocked(null);}if (displayContent.mWallpaperController.isWallpaperTarget(win)) {displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;}
//执行销毁动作win.destroySurfaceUnchecked();} while (i > 0);mWmService.mDestroySurface.clear();}
...
//enable 屏幕// Check to see if we are now in a state where the screen should// be enabled, because the window obscured flags have changed.mWmService.enableScreenIfNeededLocked();mWmService.scheduleAnimationLocked();if (DEBUG_WINDOW_TRACE) Slog.e(TAG, "performSurfacePlacementInner exit");}

大概log如下:

06-01 10:12:18.006  1890  2256 V WindowManager: Relayout Window{8d0d088 u0 com.android.settings/com.android.settings.homepage.SettingsHomepageActivity}: viewVisibility=0 req=7104x3840 {(0,0)(fillxfill) sim={adjust=resize forwardNavigation} ty=BASE_APPLICATION wanim=0x10302f2
06-01 10:12:18.006  1890  2256 V WindowManager:   fl=LAYOUT_IN_SCREEN LAYOUT_INSET_DECOR SPLIT_TOUCH HARDWARE_ACCELERATED DRAWS_SYSTEM_BAR_BACKGROUNDS
06-01 10:12:18.006  1890  2256 V WindowManager:   pfl=NO_MOVE_ANIMATION FORCE_DRAW_STATUS_BAR_BACKGROUND HIDE_NON_SYSTEM_OVERLAY_WINDOWS USE_BLAST FIT_INSETS_CONTROLLED
06-01 10:12:18.006  1890  2256 V WindowManager:   vsysui=LIGHT_STATUS_BAR LIGHT_NAVIGATION_BAR
06-01 10:12:18.006  1890  2256 V WindowManager:   apr=LIGHT_STATUS_BARS LIGHT_NAVIGATION_BARS
06-01 10:12:18.006  1890  2256 V WindowManager:   bhv=DEFAULT
06-01 10:12:18.006  1890  2256 V WindowManager:   fitSides=}
06-01 10:12:18.008  1890  2256 W WindowManager: setLayoutNeeded: callers=com.android.server.wm.WindowState.setDisplayLayoutNeeded:2671 com.android.server.wm.WindowManagerService.relayoutWindow:2419 com.android.server.wm.Session.relayout:249 
06-01 10:12:18.009  1890  2256 V WindowManager: Creating surface in session android.view.SurfaceSession@fcb7984 window WindowStateAnimator{31728a0 com.android.settings/com.android.settings.homepage.SettingsHomepageActivity} format=-1 flags=4
06-01 10:12:18.015  1890  2256 V WindowManager: Got surface: Surface(name=com.android.settings/com.android.settings.homepage.SettingsHomepageActivity)/@0xafd3c59, set left=0 top=0
06-01 10:12:18.015  1890  2256 I WindowManager: >>> OPEN TRANSACTION createSurfaceLocked
06-01 10:12:18.015  1890  2256 I WindowManager:   SURFACE CREATE pos=(0,0) HIDE: Window{8d0d088 u0 com.android.settings/com.android.settings.homepage.SettingsHomepageActivity}
06-01 10:12:18.015  1890  2256 V WindowManager: Created surface WindowStateAnimator{31728a0 com.android.settings/com.android.settings.homepage.SettingsHomepageActivity}
06-01 10:12:18.016  1890  2256 V WindowManager: performSurfacePlacementInner: entry. Called by com.android.server.wm.RootWindowContainer.performSurfacePlacement:765 com.android.server.wm.WindowSurfacePlacer.performSurfacePlacementLoop:177 com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement:126 
06-01 10:12:18.016  1890  2256 I WindowManager: >>> OPEN TRANSACTION performLayoutAndPlaceSurfaces
...
06-01 10:12:18.020  1890  2256 I WindowManager: <<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces
06-01 10:12:18.021  1890  2256 E WindowManager: performSurfacePlacementInner exit
06-01 10:12:18.021  1890  2256 V WindowManager: Already visible and does not turn on screen, skip preparing: Window{8d0d088 u0 com.android.settings/com.android.settings.homepage.SettingsHomepageActivity}
06-01 10:12:18.022  1890  2256 W WindowManager: Moving IM target from null to null since mInputMethodWindow is null
06-01 10:12:18.022  1890  2256 V WindowManager: Win Window{8d0d088 u0 com.android.settings/com.android.settings.homepage.SettingsHomepageActivity}: isDrawn=false, animating=false
06-01 10:12:18.022  1890  2256 V WindowManager: Not displayed: s=Surface(name=com.android.settings/com.android.settings.homepage.SettingsHomepageActivity)/@0xafd3c59 pv=true mDrawState=1 ph=false th=true a=false
06-01 10:12:18.022  1890  2256 V WindowManager: Relayout complete Window{8d0d088 u0 com.android.settings/com.android.settings.homepage.SettingsHomepageActivity}: outFrames=ClientWindowFrames{frame=[0,0][7104,3840] display=[0,0][7104,3840] parentFrame=[0,0][0,0]}
06-01 10:12:18.214  1890  1950 I WindowManager: commitFinishDrawingLocked: Window{d8b1e28 u0 Splash Screen com.android.settings} cur mDrawState=HAS_DRAWN
06-01 10:12:18.214  1890  1950 D ActivityTaskManager: updateWindows: starting Window{d8b1e28 u0 Splash Screen com.android.settings} isOnScreen=true allDrawn=false freezingScreen=false
06-01 10:12:18.214  1890  1950 V WindowManager: Resizing Window{d8b1e28 u0 Splash Screen com.android.settings}: configChanged=false last=Rect(0, 0 - 7104, 3840) frame=Rect(0, 0 - 7104, 3840)
06-01 10:12:18.215  1890  1950 V WindowManager: performShow on Window{8d0d088 u0 com.android.settings/com.android.settings.homepage.SettingsHomepageActivity}: mDrawState=READY_TO_SHOW readyForDisplay=true starting=false during animation: policyVis=true parentHidden=false tok.visibleRequested=true tok.visible=true animating=false tok animating=false Callers=com.android.server.wm.WindowState.performShowLocked:4372 com.android.server.wm.WindowStateAnimator.commitFinishDrawingLocked:256 com.android.server.wm.DisplayContent.lambda$new$8:1082 com.android.server.wm.DisplayContent.$r8$lambda$NJwM1ysKPNyOazqyI2QXlp2I4yA:0 
...
06-01 10:12:18.220  1890  1950 V WindowManager: Win Window{8d0d088 u0 com.android.settings/com.android.settings.homepage.SettingsHomepageActivity}: isDrawn=true, animating=true06-01 10:12:18.228  1890  1950 V WindowManager: Showing Window{8d0d088 u0 com.android.settings/com.android.settings.homepage.SettingsHomepageActivity}: mDrawState=READY_TO_SHOW readyForDisplay=true starting=false during animation: policyVis=true parentHidden=false tok.visibleRequested=true tok.visible=true animating=true tok animating=false Callers=com.android.server.wm.WindowState.performShowLocked:4387 com.android.server.wm.WindowStateAnimator.commitFinishDrawingLocked:256 com.android.server.wm.DisplayContent.lambda$new$8:1082 com.android.server.wm.DisplayContent.$r8$lambda$NJwM1ysKPNyOazqyI2QXlp2I4yA:0 

相关文章:

  • Linux操作系统学习:day01
  • leetcode67:二进制求和
  • 享元模式
  • Maven的三种项目打包方式——pom,jar,war的区别
  • 代码随想录刷题笔记-哈希表篇
  • Vue3 渲染函数 API(五)
  • 基于ensp的园区网络搭建综合实验
  • Apollo9.0 PNC源码学习之Control模块(二)
  • 【系统学C++】二、从C语言到C++(二)
  • Java应届第一年规划
  • javaFX为例的MVC案例
  • 宽睿数字平台兼容TDengine 等多种数据库,提供行情解决方案
  • Ansible——stat模块
  • java线程变量共享
  • 定时清理Linux服务器缓存shell脚本
  • 【vuex入门系列02】mutation接收单个参数和多个参数
  • 4个实用的微服务测试策略
  • Angular 4.x 动态创建组件
  • iBatis和MyBatis在使用ResultMap对应关系时的区别
  • iOS高仿微信项目、阴影圆角渐变色效果、卡片动画、波浪动画、路由框架等源码...
  • js对象的深浅拷贝
  • MYSQL如何对数据进行自动化升级--以如果某数据表存在并且某字段不存在时则执行更新操作为例...
  • 工作踩坑系列——https访问遇到“已阻止载入混合活动内容”
  • 你不可错过的前端面试题(一)
  • 前端技术周刊 2018-12-10:前端自动化测试
  • 容器服务kubernetes弹性伸缩高级用法
  • 入手阿里云新服务器的部署NODE
  • 温故知新之javascript面向对象
  • Spring Batch JSON 支持
  • 阿里云ACE认证之理解CDN技术
  • ​批处理文件中的errorlevel用法
  • # .NET Framework中使用命名管道进行进程间通信
  • ### RabbitMQ五种工作模式:
  • #define与typedef区别
  • #if和#ifdef区别
  • #常见电池型号介绍 常见电池尺寸是多少【详解】
  • (13)DroneCAN 适配器节点(一)
  • (9)目标检测_SSD的原理
  • (附源码)springboot人体健康检测微信小程序 毕业设计 012142
  • (接口封装)
  • (力扣)循环队列的实现与详解(C语言)
  • (六)软件测试分工
  • (转)Scala的“=”符号简介
  • **《Linux/Unix系统编程手册》读书笔记24章**
  • .NET Compact Framework 3.5 支持 WCF 的子集
  • .NET HttpWebRequest、WebClient、HttpClient
  • /var/lib/dpkg/lock 锁定问题
  • [1181]linux两台服务器之间传输文件和文件夹
  • [3D游戏开发实践] Cocos Cyberpunk 源码解读-高中低端机性能适配策略
  • [Angular] 笔记 20:NgContent
  • [CF482B]Interesting Array
  • [Cloud Networking] Layer3 (Continue)
  • [cocos2d-x]关于CC_CALLBACK
  • [codeforces]Levko and Permutation
  • [C语言]一维数组二维数组的大小