本文接着如下文章往下讲
Android14 WMS-窗口绘制之relayoutWindow流程(一)-Client端-CSDN博客
然后就到了Server端WMS的核心实现方法relayoutWindow里
WindowManagerService.java - OpenGrok cross reference for /frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
public class WindowManagerService extends IWindowManager.Stub
implements 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和Pid
final 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,相异为1
flagChanges = 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,相异为1
flagChanges = 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为false
boolean 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=0
win.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的可见性
mViewVisibility | Vlaue | 含义 |
---|---|---|
VISIBLE | 0x00000000 | 这个视图可见 与#setVisibility和#attr_android:visibility" android:visibility}一起使用。 |
INVISIBLE | 0x00000004 | 这个视图不可见 与#setVisibility和#attr_android:visibility" android:visibility}一起使用。 |
GONE | 0x00000008 | 这个视图是不可见的,它不占用任何空间进行布局 与#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=false
Slog.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标志位为false
w.setHasSurface(false);
ProtoLog.i(WM_DEBUG_ANIM, "createSurface %s: mDrawState=DRAW_PENDING", this);
//重置图层绘制状态
resetDrawState();
//要开始绘制图层了,要先freeze(冻住)住屏幕,等待绘制完成再Unfreeze,这里有个超时机制,即
//冻住屏幕有个最大时间WINDOW_FREEZE_TIMEOUT_DURATION--2000ms
mService.makeWindowFreezingScreenIfNeededLocked(w);
int flags = SurfaceControl.HIDDEN;
final WindowManager.LayoutParams attrs = w.mAttrs;
//如果window是加密窗口,则添加此flag
if (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=4
if (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的标志位为true
w.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=0
if (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#857
public static class Builder {
/**
* Begin building a SurfaceControl.
*/
public Builder() {
}
/**
* Construct a new {@link SurfaceControl} with the set parameters. The builder
* remains valid.
*/
@NonNull
public 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中的核心方法
下面这些流程的流程图如上
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;
}
//对应第一行标志位,表示正在layout
mInLayout = 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<6
if (++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开始一个Transaction
mWmService.openSurfaceTransaction();
try {
//执行Transaction
//下面详细解释这里
applySurfaceChangesTransaction();
} catch (RuntimeException e) {
Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
} finally {
//close surface Transaction
mWmService.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进行applySurfaceChangesTransaction
dc.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>();
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 执行mApplyPostLayoutPolicy
forAllWindows(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
//执行mApplySurfaceChangesTransaction
forAllWindows(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 window
mInputMonitor.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-25 10:56:31.956 1915 1973 V WindowManager: performShow on Window{f4647f5 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
05-25 10:56:31.962 1915 1973 V WindowManager: Showing Window{f4647f5 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
大概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=true
06-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