DisplayContent是一个WindowContainer,其对应于一个屏幕id,对于多屏幕会对应多个DisplayContent。需要注意DisplayContent代表的是逻辑显示屏,而逻辑显示屏不可能存在子屏,因此在代码中addChild是被禁止的
class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowContainer> {
DisplayContent(Display display, WindowManagerService service,
WallpaperController wallpaperController, DisplayWindowController controller) {
super(service);
setController(controller);
if (service.mRoot.getDisplayContent(display.getDisplayId()) != null) {
throw new IllegalArgumentException("Display with ID=" + display.getDisplayId()
+ " already exists=" + service.mRoot.getDisplayContent(display.getDisplayId())
+ " new=" + display);
}
//获取屏幕相关信息,屏幕id以及屏幕大小
mDisplay = display;
mDisplayId = display.getDisplayId();
mWallpaperController = wallpaperController;
display.getDisplayInfo(mDisplayInfo);
display.getMetrics(mDisplayMetrics);
isDefaultDisplay = mDisplayId == DEFAULT_DISPLAY;
mDisplayFrames = new DisplayFrames(mDisplayId, mDisplayInfo,
calculateDisplayCutoutForRotation(mDisplayInfo.rotation));
initializeDisplayBaseInfo();
mDividerControllerLocked = new DockedStackDividerController(service, this);
mPinnedStackControllerLocked = new PinnedStackController(service, this);
// We use this as our arbitrary surface size for buffer-less parents
// that don't impose cropping on their children. It may need to be larger
// than the display size because fullscreen windows can be shifted offscreen
// due to surfaceInsets. 2 times the largest display dimension feels like an
// appropriately arbitrary number. Eventually we would like to give SurfaceFlinger
// layers the ability to match their parent sizes and be able to skip
// such arbitrary size settings.
mSurfaceSize = Math.max(mBaseDisplayHeight, mBaseDisplayWidth) * 2;//渲染屏幕的大小计算
//实例化SurfaceControl
final SurfaceControl.Builder b = mService.makeSurfaceBuilder(mSession)
.setSize(mSurfaceSize, mSurfaceSize)
.setOpaque(true)//设置为透明
.setContainerLayer(true);
mWindowingLayer = b.setName("Display Root").build();
mOverlayLayer = b.setName("Display Overlays").build();
getPendingTransaction().setLayer(mWindowingLayer, 0)
.setLayerStack(mWindowingLayer, mDisplayId)
.show(mWindowingLayer)
.setLayer(mOverlayLayer, 1)
.setLayerStack(mOverlayLayer, mDisplayId)
.show(mOverlayLayer);
getPendingTransaction().apply();
// These are the only direct children we should ever have and they are permanent.
//将下面几个WindowConatiner的添加到DisplayContent中
super.addChild(mBelowAppWindowsContainers, null);
super.addChild(mTaskStackContainers, null);
super.addChild(mAboveAppWindowsContainers, null);
super.addChild(mImeWindowsContainers, null);
// Add itself as a child to the root container.
//将该displayContent作为子container添加到WMS中的RootWindowContainer
mService.mRoot.addChild(this, null);
// TODO(b/62541591): evaluate whether this is the best spot to declare the
// {@link DisplayContent} ready for use.
mDisplayReady = true;
}
}
在构造函数中,直接添加四个 :
- mBelowAppWindowsContainers:NonAppWindowContainers类型,保存了所有应该显示到App类窗口的下面的非App类的窗口。layer设置为0
- mTackStackContainer:保存了所有与App(Activities)相关的Window。layer设置为1
- mAboveAppWindowContainer:NonAppWindowContainer类型,保存了所有应该显示到App类窗口的上面的非App类的窗口,layer设置为2
-
mImeWindowContainers:NonAppWindowContainer类型,包含了所有IME window Containers。
从示意图可以看出,无论是DisplayContent或者添加到四个Containers最终的父类都是WindowContainer.
WindowContainer
作为一个window容器,其主要作用是可以添加同类型的子类,并建立一个该类型的ArrayList,并且每个子类都能直接获得其父节点,以便管理
protected void addChild(E child, Comparator<E> comparator) {
if (child.getParent() != null) {
throw new IllegalArgumentException("addChild: container=" + child.getName()
+ " is already a child of container=" + child.getParent().getName()
+ " can't add to container=" + getName());
}
int positionToAdd = -1;
if (comparator != null) {
final int count = mChildren.size();
for (int i = 0; i < count; i++) {
if (comparator.compare(child, mChildren.get(i)) < 0) {
positionToAdd = i;
break;
}
}
}
if (positionToAdd == -1) {
mChildren.add(child);
} else {
mChildren.add(positionToAdd, child);
}
onChildAdded(child);
// Set the parent after we've actually added a child in case a subclass depends on this.
child.setParent(this);
}
其中WindowList<E> mChildren = new WindowList<E>();
在DisplayContent构造函数中,最终将自己添加到WMS中mRoot作为子,其为RootWindowContainer,同样继承与WindowContainer,其泛型为DisplayContent。其为根部windowContainer。
总结
在WMS中mRoot作为屏幕内容管理器保存着对应屏幕的内容displayContent,而displayContent作为某一显示屏幕的内容管理器,保存在该屏幕四类显示的内容:显示到App类窗口的下面的非App类的窗口、与App(Activities)相关的Window、显示到App类窗口的上面的非App类的窗口、IME窗口。