Android 窗口容器树(二)—— 窗口容器树的构建

11 阅读10分钟

1. WMS 服务进程启动

1.1 WMS 服务进程启动,创建 RootWindowContainer 实例

SystemServer 进程的 startOtherServices 方法中先后启动了 AMS、WMS 服务:


private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
    ...
    // 启动 WMS 服务进程,在启动 AMS 之后
    mSystemServiceManager.startBootPhase(t, SystemService.PHASE_WAIT_FOR_SENSOR_SERVICE);
    wm = WindowManagerService.main(context, inputManager, !mFirstBoot,
            new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
    ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
            DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
    // 关注点,向 AMS 添加 WMS 实例
    mActivityManagerService.setWindowManager(wm);
    ...
}

启动 WMS 服务进程,在 WMS 的构造方法中,创建 RootWindowContainer 实例,RootWindowContainer 是窗口管理树的根节点,并创建了 DisplayAreaPolicy.Provider 对象:

private WindowManagerService(Context context, InputManagerService inputManager,
            boolean showBootMsgs, WindowManagerPolicy policy, ActivityTaskManagerService atm,
            DisplayWindowSettingsProvider displayWindowSettingsProvider,
            Supplier<SurfaceControl.Transaction> transactionFactory,
            Function<SurfaceSession, SurfaceControl.Builder> surfaceControlFactory) {
            
    mRoot = new RootWindowContainer(this);
    // 实际类型是 DisplayAreaPolicy.DefaultProvider
    mDisplayAreaPolicyProvider = DisplayAreaPolicy.Provider.fromResources(mContext.getResources());
            
}

1.2 WMS 服务进程启动,AMS、ATMS、WMS、RootWindowContainer 之间建立联系

接着调用了 AMS 的 setWindowManager 方法向 AMS 添加 WMS 实例:

public void setWindowManager(WindowManagerService wm) {
    synchronized (this) {
        mWindowManager = wm;
        mWmInternal = LocalServices.getService(WindowManagerInternal.class);
        // 向 ATMS 添加 WMS 实例
        mActivityTaskManager.setWindowManager(wm);
    }
}

向 ATMS 添加 WMS 实例:

// frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
public void setWindowManager(com.android.server.wm.WindowManagerService wm) {
    synchronized (mGlobalLock) {
        mWindowManager = wm;
        // ATMS 持有了 RootWindowContainer 实例
        mRootWindowContainer = wm.mRoot;
        mWindowOrganizerController.mTransitionController.setWindowManager(wm);
        mLifecycleManager.setWindowManager(wm);
        mTempConfig.setToDefaults();
        mTempConfig.setLocales(LocaleList.getDefault());
        mConfigurationSeq = mTempConfig.seq = 1;
        mRootWindowContainer.onConfigurationChanged(mTempConfig);
        mLockTaskController.setWindowManager(wm);
        mTaskSupervisor.setWindowManager(wm);
        // 从 mRootWindowContainer.setWindowManager(wm) 开始,就开始了窗口容器树的构建过程
        mRootWindowContainer.setWindowManager(wm);
        mBackNavigationController.setWindowManager(wm);
    }
}

将 WMS 持有的 RootWindowContainer 实例赋值给了 ATMS 的 mRootWindowContainer。接着就调用了 mRootWindowContainer 的 setWindowManager 方法,此时就开始了窗口容器树的构建过程。

2. RootWindowContaine,开始构建窗口容器树

2.1 ATMS 中调用 RootWindowContainer setWindowManager 方法,开始窗口容器树的构建流程

看一下 RootWindowContainer 的 setWindowManager 方法:

void setWindowManager(WindowManagerService wm) {
    // 将 WMS 实例传递给 RootWindowContainer
    mWindowManager = wm;
    mDisplayManager = mService.mContext.getSystemService(DisplayManager.class);
    mDisplayManager.registerDisplayListener(this, mService.mUiHandler);
    mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);

    // 获取屏幕个数
    final Display[] displays = mDisplayManager.getDisplays();
    // 遍历每一个 Display,为每一个 Display 构建一个 DisplayContent。
    for (int displayNdx = 0; displayNdx < displays.length; ++displayNdx) {
        final Display display = displays[displayNdx];
        // 为每一个 Display 创建一个 DisplayContent 对象。在窗口容器树中,DisplayContent 就代表了一个屏幕。
        final DisplayContent displayContent = new DisplayContent(display, this, mDeviceStateController);
        addChild(displayContent, POSITION_BOTTOM);
        // DEFAULT_DISPLAY 0 默认的主屏
        if (displayContent.mDisplayId == DEFAULT_DISPLAY) {
            mDefaultDisplay = displayContent;
        }
    }

    final TaskDisplayArea defaultTaskDisplayArea = getDefaultTaskDisplayArea();
    defaultTaskDisplayArea.getOrCreateRootHomeTask(ON_TOP);
    positionChildAt(POSITION_TOP, defaultTaskDisplayArea.mDisplayContent,
            false /* includingParents */);
}

通过 DisplayService 获取到了当前设备所有屏幕,接着遍历每一个 Display(屏幕),为每一个 Display 构建一个 DisplayContent。在窗口容器树中,DisplayContent 就代表了一个屏幕。

2.2 DisplayContent 初始化

看一下 DisplayContent 初始化:

DisplayContent(Display display, RootWindowContainer root,
            @NonNull DeviceStateController deviceStateController) {
    super(root.mWindowManager, "DisplayContent", FEATURE_ROOT);
    ...
    // 创建事务 
    final Transaction pendingTransaction = getPendingTransaction();
    // 开始构建层级树 
    configureSurfaces(pendingTransaction);
    // 执行事务 
    pendingTransaction.apply();
    ...
}

看一下 DisplayContent 的 configureSurfaces 方法:

private void configureSurfaces(Transaction transaction) {
    // 构建一个 SurfaceControl,表示 SurfaceFlinger 中的一个图层节点
    final SurfaceControl.Builder b = mWmService.makeSurfaceBuilder(mSession)
            .setOpaque(true)
            .setContainerLayer()
            .setCallsite("DisplayContent");
    // 设置名字后构建 (Display 0 name="XXX")Display 0 name="Built-in Screen"
    mSurfaceControl = b.setName(getName()).setContainerLayer().build();

    if (mDisplayAreaPolicy == null) {
        // Setup the policy and build the display area hierarchy.
        // Build the hierarchy only after creating the surface so it is reparented correctly
        // 关注点,构建树结构。返回一个 DisplayAreaPolicy.Provider 对象
        // 构建 DisplayArea 树结构,为不同窗口类型(如状态栏、对话框)分配层级。
        mDisplayAreaPolicy = mWmService.getDisplayAreaPolicyProvider().instantiate(
                mWmService, this /* content */, this /* root */,
                mImeWindowsContainer);
    }

    final List<DisplayArea<? extends WindowContainer>> areas =
            mDisplayAreaPolicy.getDisplayAreas(FEATURE_WINDOWED_MAGNIFICATION);
    final DisplayArea<?> area = areas.size() == 1 ? areas.get(0) : null;

    if (area != null && area.getParent() == this) {
        // The windowed magnification area should contain all non-overlay windows, so just use
        // it as the windowing layer.
        mWindowingLayer = area.mSurfaceControl;
        transaction.reparent(mWindowingLayer, mSurfaceControl);
    } else {
        // Need an additional layer for screen level animation, so move the layer containing
        // the windows to the new root.
        mWindowingLayer = mSurfaceControl;
        mSurfaceControl = b.setName("RootWrapper").build();
        transaction.reparent(mWindowingLayer, mSurfaceControl)
                .show(mWindowingLayer);
    }

    if (mOverlayLayer == null) {
        mOverlayLayer = b.setName("Display Overlays").setParent(mSurfaceControl).build();
    } else {
        transaction.reparent(mOverlayLayer, mSurfaceControl);
    }

    if (mInputOverlayLayer == null) {
        mInputOverlayLayer = b.setName("Input Overlays").setParent(mSurfaceControl).build();
    } else {
        transaction.reparent(mInputOverlayLayer, mSurfaceControl);
    }

    if (mA11yOverlayLayer == null) {
        mA11yOverlayLayer =
                b.setName("Accessibility Overlays").setParent(mSurfaceControl).build();
    } else {
        transaction.reparent(mA11yOverlayLayer, mSurfaceControl);
    }

    // 事务相关设置
    transaction
            .setLayer(mSurfaceControl, 0)
            .setLayerStack(mSurfaceControl, mDisplayId)
            .show(mSurfaceControl)
            .setLayer(mOverlayLayer, Integer.MAX_VALUE)
            .show(mOverlayLayer)
            .setLayer(mInputOverlayLayer, Integer.MAX_VALUE - 1)
            .show(mInputOverlayLayer)
            .setLayer(mA11yOverlayLayer, Integer.MAX_VALUE - 2)
            .show(mA11yOverlayLayer);
}

SurfaceControl 用于创建、配置和管理 Surface 的显示属性(如大小、位置、透明度、层级等)。

DisplayAreaPolicy 类负责建立和管理 DisplayArea 的层级结构,定义显示区域的划分策略(如系统区、应用区)。

2.3 构建 HierarchyBuilder,配置 Feature

这里直接调用 DefaultProvider 的 instantiate 进行构建 DisplayArea 树结构,为不同窗口类型(如状态栏、对话框)分配层级:

// 默认显式策略
@Override
public DisplayAreaPolicy instantiate(WindowManagerService wmService,
                                     DisplayContent content, RootDisplayArea root,
                                     DisplayArea.Tokens imeContainer) {
    // 创建一个名为 "DefaultTaskDisplayArea" 的对象作为应用窗口的默认容器,应用窗口容器
    final TaskDisplayArea defaultTaskDisplayArea = new TaskDisplayArea(content, wmService,
            "DefaultTaskDisplayArea", FEATURE_DEFAULT_TASK_CONTAINER);
    final List<com.android.server.wm.TaskDisplayArea> tdaList = new ArrayList<>();
    tdaList.add(defaultTaskDisplayArea);

    // Define the features that will be supported under the root of the whole logical
    // display. The policy will build the DisplayArea hierarchy based on this.
    // 传递 RootDisplayArea(DisplayContent)构建出一个层级树的数据结构,用于后续窗口容器树的构建。
    final HierarchyBuilder rootHierarchy = new HierarchyBuilder(root);

    // Set the essential containers (even if the display doesn't support IME).
    // HierarchyBuilder 设置输入法容器和应用窗口容器
    rootHierarchy.setImeContainer(imeContainer).setTaskDisplayAreas(tdaList);
    if (content.isTrusted()) {
        // Only trusted display can have system decorations.
        // 配置层级的支持的 Feature
        configureTrustedHierarchyBuilder(rootHierarchy, wmService, content);
    }

    // Instantiate the policy with the hierarchy defined above. This will create and attach
    // all the necessary DisplayAreas to the root.
    // 开始构建窗口容器树
    return new com.android.server.wm.DisplayAreaPolicyBuilder().setRootHierarchy(rootHierarchy).build(wmService);
}

创建一个名为 "DefaultTaskDisplayArea" 的对象作为应用窗口的默认容器,应用窗口容器。

构建出 DisplayContent 的层级树的数据结构 HierarchyBuilder,用于后续窗口容器树的构建。

接着通过 configureTrustedHierarchyBuilder 配置层级的支持的 Feature:

/**
 * Feature.mName	                     Feature.mID	                        Feature.mWindowLayers 数组为 true 的区间
 * WindowedMagnification	    FEATURE_WINDOWED_MAGNIFICATION	                            [0,31]
 * HideDisplayCutout	        FEATURE_HIDE_DISPLAY_CUTOUT	                                [0,14], 16, [18,23], [26,35]
 * OneHanded	                FEATURE_ONE_HANDED	                                        [0,23], [26,32],[34,35]
 * FullscreenMagnification  	FEATURE_FULLSCREEN_MAGNIFICATION	                        [0,12], [15,23], [26,27], [29,31], [33,35]
 * ImePlaceholder           	FEATURE_IME_PLACEHOLDER	                                    [13,14]
 */
private void configureTrustedHierarchyBuilder(HierarchyBuilder rootHierarchy,
        WindowManagerService wmService, DisplayContent content) {
    // WindowedMagnification should be on the top so that there is only one surface
    // to be magnified.
    // 通过 Feature.Builder 构造一个 Feature 对象
    // 再调用 HierarchyBuilder 对象的 addFeature 方法,将构造好的 Feature 对象保存到 HierarchyBuilder 对象内部的
    // ArrayList<DisplayAreaPolicyBuilder.Feature> mFeatures 成员中
    // 构造好了名为 WindowedMagnification 的 Feature 对象
    rootHierarchy.addFeature(new Feature.Builder(wmService.mPolicy, "WindowedMagnification",
            FEATURE_WINDOWED_MAGNIFICATION)
            .upTo(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY)  // 0-32 true
            .except(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY)// 32 false
            .setNewDisplayAreaSupplier(DisplayArea.Dimmable::new)// new 一个 DisplayArea.Dimmable 保存在 Builder 的 mNewDisplayAreaSupplier 成员中
            .build()); // 最后调用 build 方法,new 一个 Feature 返回,前面准备好的数据都作为参数传入构造方法,然后保存到 Feature 中
    if (content.isDefaultDisplay) {
        // Only default display can have cutout.
        // See LocalDisplayAdapter.LocalDisplayDevice#getDisplayDeviceInfoLocked.
        rootHierarchy.addFeature(new Feature.Builder(wmService.mPolicy, "HideDisplayCutout",
                FEATURE_HIDE_DISPLAY_CUTOUT)
                .all()
                .except(TYPE_NAVIGATION_BAR, TYPE_NAVIGATION_BAR_PANEL, TYPE_STATUS_BAR,
                        TYPE_NOTIFICATION_SHADE)
                .build())
                .addFeature(new Feature.Builder(wmService.mPolicy, "OneHanded",
                        FEATURE_ONE_HANDED)
                        .all()
                        .except(TYPE_NAVIGATION_BAR, TYPE_NAVIGATION_BAR_PANEL,
                                TYPE_SECURE_SYSTEM_OVERLAY)
                        .build());
    }
    rootHierarchy
            .addFeature(new Feature.Builder(wmService.mPolicy, "FullscreenMagnification",
                    FEATURE_FULLSCREEN_MAGNIFICATION)
                    .all()
                    .except(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY, TYPE_INPUT_METHOD,
                            TYPE_INPUT_METHOD_DIALOG, TYPE_MAGNIFICATION_OVERLAY,
                            TYPE_NAVIGATION_BAR, TYPE_NAVIGATION_BAR_PANEL)
                    .build())
            .addFeature(new Feature.Builder(wmService.mPolicy, "ImePlaceholder",
                    FEATURE_IME_PLACEHOLDER)
                    .and(TYPE_INPUT_METHOD, TYPE_INPUT_METHOD_DIALOG)
                    .build());
}

DisplayArea 节点会有自己的 Feature,来指定节点所包含的特殊功能。配置层级的支持的 Feature。一共有 5 个 Feature :

  • WindowedMagnification
  • HideDisplayCutout
  • OneHanded
  • FullscreenMagnification
  • ImePlaceholder

2.4 构建 PendingArea 树

继续调用 DisplayAreaPolicyBuilder 的 build 方法:

// 构建 PendingArea 树
// 根据 PendingArea 树构建最终的窗口容器树
Result build(WindowManagerService wmService) {
    validate();
    mRootHierarchyBuilder.build(mDisplayAreaGroupHierarchyBuilders);
    List<RootDisplayArea> displayAreaGroupRoots = new ArrayList<>(
            mDisplayAreaGroupHierarchyBuilders.size());
    // mDisplayAreaGroupHierarchyBuilders 是一个空列表
    for (int i = 0; i < mDisplayAreaGroupHierarchyBuilders.size(); i++) {
        HierarchyBuilder hierarchyBuilder = mDisplayAreaGroupHierarchyBuilders.get(i);
        hierarchyBuilder.build();
        displayAreaGroupRoots.add(hierarchyBuilder.mRoot);
    }
    // Use the default function if it is not specified otherwise.
    if (mSelectRootForWindowFunc == null) {
        mSelectRootForWindowFunc = new DefaultSelectRootForWindowFunction(
                mRootHierarchyBuilder.mRoot, displayAreaGroupRoots);
    }
    return new Result(wmService, mRootHierarchyBuilder.mRoot, displayAreaGroupRoots,
            mSelectRootForWindowFunc, mSelectTaskDisplayAreaFunc);
}

继续看一下 HierarchyBuilder 的 build 方法,这里主要通过两个循环构建了 PendingArea 树,完成之后再使用 PendingArea 树构建出目标的窗口容器树:

private void build(@Nullable List<HierarchyBuilder> displayAreaGroupHierarchyBuilders) {
    // 初始化局部变量
    final WindowManagerPolicy policy = mRoot.mWmService.mPolicy;
    // 定义最大层级数  37
    final int maxWindowLayerCount = policy.getMaxWindowLayer() + 1;
    // 存储每个窗口层级对应的 DisplayArea.Tokens 37 个
    final DisplayArea.Tokens[] displayAreaForLayer =
            new DisplayArea.Tokens[maxWindowLayerCount];
    // 存储每个 Feature 对应的 DisplayArea 列表
    final Map<Feature, List<DisplayArea<WindowContainer>>> featureAreas =
            new ArrayMap<>(mFeatures.size());
    for (int i = 0; i < mFeatures.size(); i++) {
        featureAreas.put(mFeatures.get(i), new ArrayList<>());
    }

    // 初始化 PendingArea 数组,用于临时存储每个窗口层级对应的 PendingArea,一共 37 个
    PendingArea[] areaForLayer = new PendingArea[maxWindowLayerCount];
    final PendingArea root = new PendingArea(null, 0, null);
    // areaForLayer 数组全部填充为 root
    Arrays.fill(areaForLayer, root);

    // 遍历每一个 Feature。
    final int size = mFeatures.size();
    for (int i = 0; i < size; i++) {// 遍历每一个 feature
        final Feature feature = mFeatures.get(i);
        PendingArea featureArea = null;// mParent:父节点引用; mChildren:子节点列表; mMaxLayer:覆盖的最大层级。
        
        for (int layer = 0; layer < maxWindowLayerCount; layer++) {
            if (feature.mWindowLayers[layer]) {// 检查该 Feature 是否应用于当前层级,WindowedMagnification 0~31 为 true
                // 如果现有功能是为前一层的此功能创建的,并且应用于前一层的最后一个功能与应用于当前层的功能相同,那么我们可以重用现有的 DisplayArea(因此它们可以共享相同的父 DisplayArea)
                if (featureArea == null || featureArea.mParent != areaForLayer[layer]) { // 当前 feature 对应的 PendingArea 为 null,或者 PendingArea 的父节点与与当前层的 PendingArea 不同
                    // 在 for 循环中, layer 为 0,此时 feature.mWindowLayers[0] 为 true,featureArea 为 null,那么创建一个 PendingArea 对象 WindowedMagnification:0:0,这个新创建的 WindowedMagnification:0:0 对象的 parent 是构造方法的第三个参数 areaForLayer[0],值为 Root:0:0,接着将这个新创建的 WindowedMagnification:0:0 添加到 areaForLayer[0] Root:0:0 的子节点中,最后将 areaForLayer[0] 指向这个新创建的 WindowedMagnification:0:0。
                    featureArea = new PendingArea(feature, layer, areaForLayer[layer]);// 新建 feature 的 PendingArea
                    areaForLayer[layer].mChildren.add(featureArea);
                }
                areaForLayer[layer] = featureArea;
            } else {
                featureArea = null;
            }
        }
    }

    // 生成叶子节点
    PendingArea leafArea = null;
    int leafType = LEAF_TYPE_TOKENS;
    for (int layer = 0; layer < maxWindowLayerCount; layer++) {
        // 获取叶子节点类型
        int type = typeOfLayer(policy, layer);
        if (leafArea == null || leafArea.mParent != areaForLayer[layer]
                || type != leafType) {
            // new 一个 PendingArea 对象,然后添加到 areaForLayer[layer] 的子节点中,成为叶子节点。
            leafArea = new PendingArea(null /* feature */, layer, areaForLayer[layer]);
            areaForLayer[layer].mChildren.add(leafArea);
            leafType = type;
            if (leafType == LEAF_TYPE_TASK_CONTAINERS) {
            // 如果叶子节点类型是 LEAF_TYPE_IME_CONTAINERS,也就是 layer 等于 2,则做以下处理:
                // 给 areaForLayer[layer] 再添加一个叶子节点
                addTaskDisplayAreasToApplicationLayer(areaForLayer[layer]);
                // // displayAreaGroupHierarchyBuilders是一个空的列表,这个方法就不用管了
                addDisplayAreaGroupsToApplicationLayer(areaForLayer[layer],
                        displayAreaGroupHierarchyBuilders);
                // 接着将叶子节点 leafArea 的 mSkipTokens 设置为 true,那么后续在根据PendingArea 树生成 DisplayArea 层级结构的时候,就不会为这个 PendingArea 对象生成一个 DisplayArea 对象了。
                leafArea.mSkipTokens = true;
            } else if (leafType == LEAF_TYPE_IME_CONTAINERS) {// 如果叶子节点类型是 LEAF_TYPE_TASK_CONTAINERS,也就是 layer 等于 13 或者 14
                // 后续根据 PendingArea 生成 DisplayArea.Tokens 的时候,不再为当前节点生成 DisplayArea.Tokens,而是用之前保存在 HierarchyBuilder.mImeContainer 的 ImeContainer
                leafArea.mExisting = mImeContainer;
                leafArea.mSkipTokens = true;
            }
        }
        // 设置叶子节点的最大层级
        leafArea.mMaxLayer = layer;
    }
    // 接着调用 computeMaxLayer 计算非叶子节点的 mMaxLayer。在此之前,非叶子节点的 mMaxLayer 都是 0,这里调用 computerMaxLayer 方法,将这些值计算出来:
    root.computeMaxLayer();

    // PendingArea 树就构造好以后,基于 PendingArea 树生成窗口容器树 DisplayAreas
    root.instantiateChildren(mRoot, displayAreaForLayer, 0, featureAreas);


    mRoot.onHierarchyBuilt(mFeatures, displayAreaForLayer, featureAreas);
}

2.5 基于 PendingArea 树,生成窗口容器树

void instantiateChildren(DisplayArea<DisplayArea> parent, DisplayArea.Tokens[] areaForLayer,
        int level, Map<Feature, List<DisplayArea<WindowContainer>>> areas) {
    // 1. 子区域按照它们的最小层级进行升序排列
    mChildren.sort(Comparator.comparingInt(pendingArea -> pendingArea.mMinLayer));
    // 2. 遍历孩子将 PendingArea 转换成 DisplayArea
    for (int i = 0; i < mChildren.size(); i++) {
        final PendingArea child = mChildren.get(i);
        // 将该节点转成对应的 DisplayArea
        final DisplayArea area = child.createArea(parent, areaForLayer);
        if (area == null) {
            // TaskDisplayArea and ImeContainer can be set at different hierarchy, so it can
            // be null.
            continue;
        }
        // 将返回的 area 设置为孩子,第一次执行的时候 root 就是 DisplayContent
        parent.addChild(area, WindowContainer.POSITION_TOP);
        if (child.mFeature != null) {
            // 让 Feature 对应的容器里添加创建的 DisplayArea
            areas.get(child.mFeature).add(area);
        }
        // 开始迭代构建
        child.instantiateChildren(area, areaForLayer, level + 1, areas);
    }
}
private DisplayArea createArea(DisplayArea<DisplayArea> parent,
        DisplayArea.Tokens[] areaForLayer) {
    // 当 mExisting 不为 null,前面分析的 TaskDisplayArea 和 ImeContainer 的情况,此时不需要再创建 DisplayArea 对象,直接用 mExisting
    if (mExisting != null) {
        // asTokens,方法定义在 DisplayArea 中默认返回 null,只有 DisplayArea.Tokens 返回本身。 而 ImeContainer 是继承 DisplayArea.Tokens 的,所以有返回值。
        if (mExisting.asTokens() != null) {
            // Store the WindowToken container for layers
            // 只有输入法满足
            fillAreaForLayers(mExisting.asTokens(), areaForLayer);
        }
        return mExisting;
    }
    // mSkipTokens 为 true,直接 return,mSkipTokens 是和 mExisting 是同一个逻辑下设置的。
    if (mSkipTokens) {
        return null;
    }
    // 定义 DisplayArea 的类型
    DisplayArea.Type type;
    if (mMinLayer > APPLICATION_LAYER) {
        type = DisplayArea.Type.ABOVE_TASKS;
    } else if (mMaxLayer < APPLICATION_LAYER) {
        type = DisplayArea.Type.BELOW_TASKS;
    } else {
        type = DisplayArea.Type.ANY;
    }
    // DisplayArea 的类型
    if (mFeature == null) {// leaf 的 mFeature null
        // 构建返回的 Leaf
        final DisplayArea.Tokens leaf = new DisplayArea.Tokens(parent.mWmService, type,
                "Leaf:" + mMinLayer + ":" + mMaxLayer);
        fillAreaForLayers(leaf, areaForLayer);// 给对应覆盖的层级都需要赋值
        return leaf;
    } else {// 创建 DisplayArea 对象。如果 mFeature不为 null,那么创建一个 DisplayArea 对象,注意这里构造函数 name 参数传入的是 mFeature.mName + ":" + mMinLayer + ":" + mMaxLayer,包含了 Feature 名,纵向层级范围信息。
        return mFeature.mNewDisplayAreaSupplier.create(parent.mWmService, type,
                mFeature.mName + ":" + mMinLayer + ":" + mMaxLayer, mFeature.mId);
    }
}

该文章为第一次阅读源码所总结,后续会进行补充,学习的本质是反复。