win.setFrameNumber(frameNumber);
final DisplayContent dc = win.getDisplayContent();
// 如果此时没有执行Configuration的更新,试图结束衔接动画
if (!dc.mWaitingForConfig) {
win.finishSeamlessRotation(false /* timeout */);
}
// 用来标记属性是否发生变化
int attrChanges = 0;
int flagChanges = 0;
int privateFlagChanges = 0;
int privflagChanges = 0;
if (attrs != null) {
// 调整特殊类型的Window#attrs属性
displayPolicy.adjustWindowParamsLw(win, attrs, pid, uid);
// 针对壁纸窗口调整Window#attrs属性
win.mToken.adjustWindowParams(win, attrs);
// 调整mSystemUiVisibility属性,控制status bar的显示
if (seq == win.mSeq) {
int systemUiVisibility = attrs.systemUiVisibility
| attrs.subtreeSystemUiVisibility;
…
}
win.mSystemUiVisibility = systemUiVisibility;
}
// PRIVATE_FLAG_PRESERVE_GEOMETRY将忽略新x、y、width、height值,使用旧值
if ((attrs.privateFlags & WindowManager.LayoutParams.PRIVATE_FLAG_PRESERVE_GEOMETRY)
!= 0) {
attrs.x = win.mAttrs.x;
attrs.y = win.mAttrs.y;
attrs.width = win.mAttrs.width;
attrs.height = win.mAttrs.height;
}
// 确定flag是否发生变化
flagChanges = win.mAttrs.flags ^ attrs.flags;
privateFlagChanges = win.mAttrs.privateFlags ^ attrs.privateFlags;
attrChanges = win.mAttrs.copyFrom(attrs);
// 根据flag是否发生变化做出对应响应,略…
…
}
// 根据应用请求设置宽高,获取窗口缩放比例
win.setWindowScale(win.mRequestedWidth, win.mRequestedHeight);
// 窗口此时的可见状态
final int oldVisibility = win.mViewVisibility;
// 窗口是否要由不可见状态转变为可见状态
final boolean becameVisible =
(oldVisibility == View.INVISIBLE || oldVisibility == View.GONE)
&& viewVisibility == View.VISIBLE;
// 是否需要移除IME窗口
boolean imMayMove = (flagChanges & (FLAG_ALT_FOCUSABLE_IM | FLAG_NOT_FOCUSABLE)) != 0
|| becameVisible;
// 确定是否需要更新focus状态,第一次执行relayout时,mRelayoutCalled为false
boolean focusMayChange = win.mViewVisibility != viewVisibility
|| ((flagChanges & FLAG_NOT_FOCUSABLE) != 0)
|| (!win.mRelayoutCalled);
// 如果窗口可见性发生变化,且该窗口允许显示在壁纸之上,则对壁纸窗口进行处理
boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
&& (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
wallpaperMayMove |= (flagChanges & FLAG_SHOW_WALLPAPER) != 0;
win.mRelayoutCalled = true; // 设置WindowState#mRelayoutCalled为true
win.mInRelayout = true; // 设置WindowState#mInRelayout为true,表示在relayout过程中,relayout完毕后,重置为false
// 更新窗口的可见性
win.setViewVisibility(viewVisibility);
// 通知DisplayContent,需要进行重新布局
win.setDisplayLayoutNeeded();
// 表示是否在等待设置Inset
win.mGivenInsetsPending = (flags & WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;
// 如果窗口可见,进行重新布局
final boolean shouldRelayout = viewVisibilit