android wms——DisplayContent

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;
    }
}

在构造函数中,直接添加四个 :

  1. mBelowAppWindowsContainers:NonAppWindowContainers类型,保存了所有应该显示到App类窗口的下面的非App类的窗口。layer设置为0
  2. mTackStackContainer:保存了所有与App(Activities)相关的Window。layer设置为1
  3. mAboveAppWindowContainer:NonAppWindowContainer类型,保存了所有应该显示到App类窗口的上面的非App类的窗口,layer设置为2
  4. mImeWindowContainers:NonAppWindowContainer类型,包含了所有IME window Containers。


    类简单示意图.jpg

从示意图可以看出,无论是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窗口。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容