public int addWindow(Session session, IWindow client, int seq, WindowManager.LayoutParams attrs, int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets, InputChannel outInputChannel) { int res = mPolicy.checkAddPermission(attrs, appOp); //... synchronized(mWindowMap) { //... final DisplayContent displayContent = getDisplayContentLocked(displayId); if (displayContent == null) { Slog.w(TAG, "Attempted to add window to a display that does not exist: " + displayId + ". Aborting."); return WindowManagerGlobal.ADD_INVALID_DISPLAY; } //... WindowToken token = mTokenMap.get(attrs.token); //... // 新的WindowState对象在其构造函数中根据窗口范例初始化了其主序mBaseLayer和mSubLayer win = new WindowState(this, session, client, token, attachedWindow, appOp[0], seq, attrs, viewVisibility, displayContent); ...... return res;}
//根据范例返回窗口的种类,从1-31, public int windowTypeToLayerLw(int type) { if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) { return 2; } switch (type) { case TYPE_UNIVERSE_BACKGROUND: return 1; case TYPE_PRIVATE_PRESENTATION: return 2; case TYPE_WALLPAPER: // wallpaper is at the bottom, though the window manager may move it. return 2; case TYPE_PHONE: return 3; case TYPE_SEARCH_BAR: return 4; ... case TYPE_HIDDEN_NAV_CONSUMER: return 30; /// M:JB migration case TYPE_TOP_MOST: return 31; } Log.e(TAG, "Unknown window type: " + type); return 2; }
WindowManagerPolicy.subWindowTypeToLayerLw
盘算子窗口位置
public int subWindowTypeToLayerLw(int type) { switch (type) { case TYPE_APPLICATION_PANEL: case TYPE_APPLICATION_ATTACHED_DIALOG: return APPLICATION_PANEL_SUBLAYER;//便是1 case TYPE_APPLICATION_MEDIA: return APPLICATION_MEDIA_SUBLAYER;//便是-2 case TYPE_APPLICATION_MEDIA_OVERLAY: return APPLICATION_MEDIA_OVERLAY_SUBLAYER;//便是-1 case TYPE_APPLICATION_SUB_PANEL: return APPLICATION_SUB_PANEL_SUBLAYER;//便是2 } Log.e(TAG, "Unknown sub-window type: " + type); return 0; }
WindowManagerService.getLayoutHintLw: 盘算窗口的巨细
public int addWindow(Session session, IWindow client, int seq, WindowManager.LayoutParams attrs, int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets, InputChannel outInputChannel) { ...... final Rect taskBounds; final boolean floatingStack; if (atoken != null && atoken.getTask() != null) { taskBounds = mTmpRect; //重点:这里getBounds得到的尺寸是在Activity启动阶段调用setBounds设置的 atoken.getTask().getBounds(mTmpRect); floatingStack = atoken.getTask().isFloating(); } else { taskBounds = null; floatingStack = false; } //重点方法getLayoutHintLw if (displayPolicy.getLayoutHintLw(win.mAttrs, taskBounds, displayFrames, floatingStack, outFrame, outContentInsets, outStableInsets, outOutsets, outDisplayCutout)) { res |= WindowManagerGlobal.ADD_FLAG_ALWAYS_CONSUME_SYSTEM_BARS; } return res;}6、DisplayPolicy.getLayoutHintLw
public boolean getLayoutHintLw(LayoutParams attrs, Rect taskBounds, DisplayFrames displayFrames, boolean floatingStack, Rect outFrame, Rect outContentInsets, Rect outStableInsets, Rect outOutsets, DisplayCutout.ParcelableWrapper outDisplayCutout) { //这里获取和窗口尺寸盘算相干的flag, //如WindowManager.LayoutParams.FLAG_FULLSCREEN,全屏 //WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS等,半透明状态栏 final int fl = PolicyControl.getWindowFlags(null, attrs); final int pfl = attrs.privateFlags; //获取和SystemUI相干 flag, //这些flag界说在View中,大多和是否全屏表现,是否潜伏状态栏,是否潜伏导航栏相干 final int requestedSysUiVis = PolicyControl.getSystemUiVisibility(null, attrs); final int sysUiVis = requestedSysUiVis | getImpliedSysUiFlagsForLayout(attrs); //屏幕旋转角度 final int displayRotation = displayFrames.mRotation; //是否使用超出真实屏幕的底部像素值 final boolean useOutsets = outOutsets != null && shouldUseOutsets(attrs, fl); if (useOutsets) { //这个值界说在configs.xml中(config_windowOutsetBottom),默以为0, int outset = mWindowOutsetBottom; if (outset > 0) { if (displayRotation == Surface.ROTATION_0) { outOutsets.bottom += outset; } else if (displayRotation == Surface.ROTATION_90) { outOutsets.right += outset; } else if (displayRotation == Surface.ROTATION_180) { outOutsets.top += outset; } else if (displayRotation == Surface.ROTATION_270) { outOutsets.left += outset; } } } final boolean layoutInScreen = (fl & FLAG_LAYOUT_IN_SCREEN) != 0; final boolean layoutInScreenAndInsetDecor = layoutInScreen && (fl & FLAG_LAYOUT_INSET_DECOR) != 0; final boolean screenDecor = (pfl & PRIVATE_FLAG_IS_SCREEN_DECOR) != 0; if (layoutInScreenAndInsetDecor && !screenDecor) { if ((sysUiVis & SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0) { //包罗状态栏导航栏的屏幕可见解区 Rect(0, 0 - 800, 480) outFrame.set(displayFrames.mUnrestricted); } else { //除启发航栏的内容地域 Rect(0, 0 - 800, 396) outFrame.set(displayFrames.mRestricted); } final Rect sf; //悬浮栈,窗口模式为自由窗口大概画中画的栈 if (floatingStack) { sf = null; } else { //除开状态栏,导航栏的内容地域 Rect(0, 57 - 800, 396) sf = displayFrames.mStable; } final Rect cf; if (floatingStack) { cf = null; } else if ((sysUiVis & View.SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0) { if ((fl & FLAG_FULLSCREEN) != 0) { //除启发航栏的内容地域 Rect(0, 0 - 800, 396) cf = displayFrames.mStableFullscreen; } else { //除开状态栏,导航栏的内容地域 Rect(0, 57 - 800, 396) cf = displayFrames.mStable; } } else if ((fl & FLAG_FULLSCREEN) != 0 || (fl & FLAG_LAYOUT_IN_OVERSCAN) != 0) { //真实屏幕的尺寸 Rect(0, 0 - 800, 480) cf = displayFrames.mOverscan; } else { //除开状态栏,导航栏,输入法的内容地域 Rect(0, 57 - 800, 396) cf = displayFrames.mCurrent; } if (taskBounds != null) { //taskBounds为Activity自己设置的巨细,Rect(400, 57 - 800, 396) outFrame.intersect(taskBounds); } InsetUtils.insetsBetweenFrames(outFrame, cf, outContentInsets); InsetUtils.insetsBetweenFrames(outFrame, sf, outStableInsets); outDisplayCutout.set(displayFrames.mDisplayCutout.calculateRelativeTo(outFrame) .getDisplayCutout()); return mForceShowSystemBars; } else { if (layoutInScreen) { //包罗状态栏导航栏的屏幕可见解区 Rect(0, 0 - 800, 480) outFrame.set(displayFrames.mUnrestricted); } else { //除开状态栏,导航栏的内容地域 Rect(0, 57 - 800, 396) outFrame.set(displayFrames.mStable); } if (taskBounds != null) { //taskBounds为Activity自己设置的巨细,Rect(400, 57 - 800, 396) outFrame.intersect(taskBounds); } outContentInsets.setEmpty(); outStableInsets.setEmpty(); outDisplayCutout.set(DisplayCutout.NO_CUTOUT); return mForceShowSystemBars; } }
DisplayFrames一些关键先容
//DisplayFrames.java//以模仿器尺寸Rect(0, 0 - 800, 480)为例 /** * 真实屏幕的尺寸 Rect(0, 0 - 800, 480) */ public final Rect mOverscan = new Rect(); /** * 除开状态栏,导航栏,输入法的内容地域 Rect(0, 57 - 800, 396) */ public final Rect mCurrent = new Rect();/** * 包罗状态栏导航栏的屏幕可见解区 Rect(0, 0 - 800, 480) */ public final Rect mUnrestricted = new Rect(); /** * 除启发航栏的内容地域 Rect(0, 0 - 800, 396) */ public final Rect mRestricted = new Rect();/** 除开状态栏,导航栏的内容地域 Rect(0, 57 - 800, 396) */ public final Rect mStable = new Rect(); /** * 除启发航栏的内容地域 Rect(0, 0 - 800, 396) */ public final Rect mStableFullscreen = new Rect();2、窗口尺寸盘算
public int relayoutWindow(Session session, IWindow client, int seq, LayoutParams attrs, int requestedWidth, int requestedHeight, int viewVisibility, int flags, long frameNumber, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, Rect outVisibleInsets, Rect outStableInsets, Rect outOutsets, Rect outBackdropFrame, DisplayCutout.ParcelableWrapper outCutout, MergedConfiguration mergedConfiguration, SurfaceControl outSurfaceControl, InsetsState outInsetsState) { ...... if (viewVisibility != View.GONE) { //requestedWidth和requestedHeight是Activity窗口颠末丈量后得到的自己的想要的宽高 win.setRequestedSize(requestedWidth, requestedHeight); } ...... //WMS核心功能,革新体系UI,这内里会去盘算窗口尺寸, //遍历体系所有窗口调用其WindowState的computeFrameLw方法 mWindowPlacerLocked.performSurfacePlacement(true /* force */); ...... win.getCompatFrame(outFrame); ...... }
DisplayPolicy.layoutWindowLw
public void layoutWindowLw(WindowState win, WindowState attached, DisplayFrames displayFrames) { ...... final WindowFrames windowFrames = win.getWindowFrames(); final Rect pf = windowFrames.mParentFrame; final Rect df = windowFrames.mDisplayFrame; final Rect of = windowFrames.mOverscanFrame; final Rect cf = windowFrames.mContentFrame; final Rect vf = windowFrames.mVisibleFrame; final Rect dcf = windowFrames.mDecorFrame; final Rect sf = windowFrames.mStableFrame; ...... //颠末各种条件判断,末了会对上述Rect赋值,赋的值全部来自DisplayFrames中 ..... //有了上述窗口的底子界限之后便开始窗口自己尺寸的盘算了 win.computeFrameLw(); .....}