概述
Android12开始,窗口的组织方式发生了变化,比如增加了Feature等结构,用来支持统一的放大缩小等处理,从而窗口体系也做了相应调整。本文旨在整理Android12窗口容器的树形结构。
当前的Container体系情况可通过以下方式查看:
dumpsys activity containers
所有的窗口容器皆是WindowContainer的子类。涉及到的类图如下:
最终整理的窗口体系图:
树的生成过程
整个窗口体系的构建序列图如下:
RootWindowContainer的初始化:
platform/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
public class WindowManagerService extends IWindowManager.Stub
implements Watchdog.Monitor,WindowManagerPolicy.WindowManagerFuncs {
final RootWindowContainer mRoot;
private WindowManagerService(...) {
...
mRoot = new RootWindowContainer(this);
...
}
...
}
DisplayContent的初始化:
platform/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
public int addWindow(Session session, IWindow client, LayoutParams attrs, int viewVisibility,
int displayId, int requestUserId, @InsetsType int requestedVisibleTypes,
InputChannel outInputChannel, InsetsState outInsetsState,
InsetsSourceControl.Array outActiveControls, Rect outAttachedFrame,
float[] outSizeCompatScale) {
...
final DisplayContent dc = getDisplayContentOrCreate(displayId, null /* token */);
...
}
private DisplayContent getDisplayContentOrCreate(int displayId, IBinder token) {
DisplayContent displayContent = getDisplayContent(displayId);
if (displayContent != null) {
return displayContent;
}
return mRoot.getDisplayContentOrCreate(displayId);
}
platform/frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
DisplayContent getDisplayContentOrCreate(int displayId) {
DisplayContent displayContent = getDisplayContent(displayId);
if (displayContent != null) {
return displayContent;
}
if (mDisplayManager == null) {
return null;
}
final Display display = mDisplayManager.getDisplay(displayId);
if (display == null) {
return null;
}
displayContent = new DisplayContent(display, this, mDeviceStateController);
addChild(displayContent, POSITION_BOTTOM);
}
Feature和DisplayArea
Android中有0~36一共37个Layer。每个layer的值代表该layer在Z轴中的顺序,值越大的越靠上。每个window都有一个type,分类如下:
Application windows(应用窗口): 1~99
Sub-windows(子窗口): 1000~1999
System windows(系统窗口): 2000~2999
决定窗口显示层级的并不是type,而是layer。
type与layer的对应关系如下:
platform/frameworks/base/services/core/java/com/android/server/policy/WindowManagerPolicy.java
default int getWindowLayerFromTypeLw(int type, boolean canAddInternalSystemWindow,
boolean roundedCornerOverlay) {
// Always put the rounded corner layer to the top most.
if (roundedCornerOverlay && canAddInternalSystemWindow) {
return getMaxWindowLayer();
}
if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
return APPLICATION_LAYER;
}
switch (type) {
case TYPE_WALLPAPER:
// wallpaper is at the bottom, though the window manager may move it.
return 1;
case TYPE_PRESENTATION:
case TYPE_PRIVATE_PRESENTATION:
case TYPE_DOCK_DIVIDER:
case TYPE_QS_DIALOG:
case TYPE_PHONE:
return 3;
case TYPE_SEARCH_BAR:
return 4;
case TYPE_INPUT_CONSUMER:
return 5;
case TYPE_SYSTEM_DIALOG:
return 6;
case TYPE_TOAST:
// toasts and the plugged-in battery thing
return 7;
case TYPE_PRIORITY_PHONE:
// SIM errors and unlock. Not sure if this really should be in a high layer.
return 8;
case TYPE_SYSTEM_ALERT:
// like the ANR / app crashed dialogs
// Type