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;
}
}
在構造函數(shù)中,直接添加四個 :
- 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,并且每個子類都能直接獲得其父節(jié)點预明,以便管理
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構造函數(shù)中,最終將自己添加到WMS中mRoot作為子耙箍,其為RootWindowContainer撰糠,同樣繼承與WindowContainer,其泛型為DisplayContent辩昆。其為根部windowContainer阅酪。
總結
在WMS中mRoot作為屏幕內(nèi)容管理器保存著對應屏幕的內(nèi)容displayContent,而displayContent作為某一顯示屏幕的內(nèi)容管理器,保存在該屏幕四類顯示的內(nèi)容:顯示到App類窗口的下面的非App類的窗口术辐、與App(Activities)相關的Window砚尽、顯示到App類窗口的上面的非App類的窗口、IME窗口辉词。