ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Android14 WMS-DisplayArea层级结构生成

2026/9/14 17:20:22 拓冰建站 浏览量
Android14 WMS-DisplayArea层级结构生成

每个手机可以有多个屏幕, 一个屏幕是一个displaycont, 下面从displaycont开始, 看下层级结构是如何构建的

02-02 19:55:04.258  3530  3530 V jinyanmeiWMS: java.lang.RuntimeException: jinyanmeiWMS
02-02 19:55:04.258  3530  3530 V jinyanmeiWMS: 	at com.android.server.wm.DisplayAreaPolicyBuilder$Feature.<init>(DisplayAreaPolicyBuilder.java:666)
02-02 19:55:04.258  3530  3530 V jinyanmeiWMS: 	at com.android.server.wm.DisplayAreaPolicyBuilder$Feature.<init>(DisplayAreaPolicyBuilder.java:0)
02-02 19:55:04.258  3530  3530 V jinyanmeiWMS: 	at com.android.server.wm.DisplayAreaPolicyBuilder$Feature$Builder.build(DisplayAreaPolicyBuilder.java:813)
02-02 19:55:04.258  3530  3530 V jinyanmeiWMS: 	at com.android.server.wm.DisplayAreaPolicy$DefaultProvider.configureTrustedHierarchyBuilder(DisplayAreaPolicy.java:131)
02-02 19:55:04.258  3530  3530 V jinyanmeiWMS: 	at com.android.server.wm.DisplayAreaPolicy$DefaultProvider.instantiate(DisplayAreaPolicy.java:113)
02-02 19:55:04.258  3530  3530 V jinyanmeiWMS: 	at com.android.server.wm.DisplayContent.configureSurfaces(DisplayContent.java:1307)
02-02 19:55:04.258  3530  3530 V jinyanmeiWMS: 	at com.android.server.wm.DisplayContent.<init>(DisplayContent.java:1209)
02-02 19:55:04.258  3530  3530 V jinyanmeiWMS: 	at com.android.server.wm.RootWindowContainer.setWindowManager(RootWindowContainer.java:1273)
02-02 19:55:04.258  3530  3530 V jinyanmeiWMS: 	at com.android.server.wm.ActivityTaskManagerService.setWindowManager(ActivityTaskManagerService.java:1040)
02-02 19:55:04.258  3530  3530 V jinyanmeiWMS: 	at com.android.server.am.ActivityManagerService.setWindowManager(ActivityManagerService.java:2052)
02-02 19:55:04.258  3530  3530 V jinyanmeiWMS: 	at com.android.server.SystemServer.startOtherServices(SystemServer.java:1615)
02-02 19:55:04.258  3530  3530 V jinyanmeiWMS: 	at com.android.server.SystemServer.run(SystemServer.java:942)
02-02 19:55:04.258  3530  3530 V jinyanmeiWMS: 	at com.android.server.SystemServer.main(SystemServer.java:664)
02-02 19:55:04.258  3530  3530 V jinyanmeiWMS: 	at java.lang.reflect.Method.invoke(Native Method)
02-02 19:55:04.258  3530  3530 V jinyanmeiWMS: 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
02-02 19:55:04.258  3530  3530 V jinyanmeiWMS: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:949)

构造displayContent

DisplayContent.java   DisplayContent(Display display, RootWindowContainer root,@NonNull DeviceStateController deviceStateController) {final Transaction pendingTransaction = getPendingTransaction();configureSurfaces(pendingTransaction);pendingTransaction.apply();
}

DisplayContent.java   private void configureSurfaces(Transaction transaction) {final SurfaceControl.Builder b = mWmService.makeSurfaceBuilder(mSession).setOpaque(true).setContainerLayer().setCallsite("DisplayContent");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 correctlymDisplayAreaPolicy = mWmService.getDisplayAreaPolicyProvider().instantiate(mWmService, this /* content */, this /* root */,mImeWindowsContainer);}final List<DisplayArea<? extends WindowContainer>> areas =mDisplayAreaPolicy.getDisplayAreas(FEATURE_WINDOWED_MAGNIFICATION);

 构建DisplayArea

   DisplayAreaPolicy.java/** Provider for platform-default display area policy. */static final class DefaultProvider implements DisplayAreaPolicy.Provider {@Overridepublic DisplayAreaPolicy instantiate(WindowManagerService wmService,DisplayContent content, RootDisplayArea root,DisplayArea.Tokens imeContainer) {final TaskDisplayArea defaultTaskDisplayArea = new TaskDisplayArea(content, wmService,"DefaultTaskDisplayArea", FEATURE_DEFAULT_TASK_CONTAINER);final List<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.final HierarchyBuilder rootHierarchy = new HierarchyBuilder(root);// Set the essential containers (even if the display doesn't support IME).rootHierarchy.setImeContainer(imeContainer).setTaskDisplayAreas(tdaList);if (content.isTrusted()) {// Only trusted display can have system decorations.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 DisplayAreaPolicyBuilder().setRootHierarchy(rootHierarchy).build(wmService);}

这个函数又分为3步

1. 初始化DefaultTaskDisplayArea

final TaskDisplayArea defaultTaskDisplayArea = new TaskDisplayArea(content, wmService,"DefaultTaskDisplayArea", FEATURE_DEFAULT_TASK_CONTAINER);

 生成一个list, 将刚生成的defaultTaskDisplayArea 加进入, 并且设置到HierarchyBuilder的list中
final List<TaskDisplayArea> tdaList = new ArrayList<>();

tdaList.add(defaultTaskDisplayArea);

    TaskDisplayArea(DisplayContent displayContent, WindowManagerService service, String name,int displayAreaFeature, boolean createdByOrganizer,boolean canHostHomeTask) {super(service, Type.ANY, name, displayAreaFeature);mDisplayContent = displayContent;mRootWindowContainer = service.mRoot;mAtmService = service.mAtmService;mCreatedByOrganizer = createdByOrganizer;mCanHostHomeTask = canHostHomeTask;}

2.初始化HierarchyBuilder

DisplayAreaPolicyBuilder.javastatic class HierarchyBuilder {private static final int LEAF_TYPE_TASK_CONTAINERS = 1;private static final int LEAF_TYPE_IME_CONTAINERS = 2;private static final int LEAF_TYPE_TOKENS = 0;private final RootDisplayArea mRoot;private final ArrayList<DisplayAreaPolicyBuilder.Feature> mFeatures = new ArrayList<>();private final ArrayList<TaskDisplayArea> mTaskDisplayAreas = new ArrayList<>();HierarchyBuilder(RootDisplayArea root) {mRoot = root;}

这里的root是 DisplayCont

然后调用  rootHierarchy.setImeContainer(imeContainer).setTaskDisplayAreas(tdaList);

HierarchyBuilder里面有一个两个List

其中一个存储TaskDisplayArea对象, 虽然是list,但是目前TaskDisplayArea只在这里被创建,即目前一个DisplayContent只有一个名为“DefaultTaskDisplayArea”的TaskDisplayArea。

另外一个存储Feature

DisplayAreaPolicyBuilder.HierarchyBuilder.javaHierarchyBuilder setTaskDisplayAreas(List<TaskDisplayArea> taskDisplayAreas) {mTaskDisplayAreas.clear();mTaskDisplayAreas.addAll(taskDisplayAreas);return this;}

3.为HierarchyBuilder添加Feature

    static final class DefaultProvider implements DisplayAreaPolicy.Provider {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.rootHierarchy.addFeature(new Feature.Builder(wmService.mPolicy, "WindowedMagnification",FEATURE_WINDOWED_MAGNIFICATION).upTo(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY).except(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY)// Make the DA dimmable so that the magnify window also mirrors the dim layer..setNewDisplayAreaSupplier(DisplayArea.Dimmable::new).build());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());}

可以看到分为两种情况, 默认屏幕要多三中Feature

下面来看Feature是如何构造的

        static class Builder {private final WindowManagerPolicy mPolicy;private final String mName;private final int mId;private final boolean[] mLayers;private NewDisplayAreaSupplier mNewDisplayAreaSupplier = DisplayArea::new;private boolean mExcludeRoundedCorner = true;Builder(WindowManagerPolicy policy, String name, int id) {mPolicy = policy;mName = name;mId = id;mLayers = new boolean[mPolicy.getMaxWindowLayer() + 1];}

首先Feature代表的是DisplayArea的一个特征,可以根据Feature来对不同的DisplayArea进行划分。

它的成员变量 有:

mName,很好理解,这个Feature的名字,如上面的“WindowedMagnification”,“HideDisplayCutout”之类的,后续DisplayArea层级结构建立起来后,每个DisplayArea的名字用的就是当前DisplayArea对应的那个Feature的名字。
mId,Feature的ID,如上面的FEATURE_WINDOWED_MAGNIFICATION和FEATURE_HIDE_DISPLAY_CUTOUT,虽说是Feature的ID,因为Feature又是DisplayArea的特征,所以这个ID也可以直接代表DisplayArea的一种特征。
mWindowLayers,代表了这个DisplayArea可以包含哪些层级对应的窗口,后续会分析到。
mNewDisplayAreaSupplier

            rootHierarchy.addFeature(new Feature.Builder(wmService.mPolicy, "WindowedMagnification",FEATURE_WINDOWED_MAGNIFICATION).upTo(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY).except(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY)// Make the DA dimmable so that the magnify window also mirrors the dim layer..setNewDisplayAreaSupplier(DisplayArea.Dimmable::new).build());
            /*** Set that the feature applies window types that are layerd at or below the layer of* the given window type.*/Builder upTo(int typeInclusive) {final int max = layerFromType(typeInclusive, false);for (int i = 0; i < max; i++) {mLayers[i] = true;}set(typeInclusive, true);return this;}

返回32, 首先将[0, 31] = true, 然后将32改为true;

mLayers[0, 32] = true;

            Builder except(int... types) {for (int i = 0; i < types.length; i++) {int type = types[i];set(type, false);}return this;}

except 是[32]设置为false

所以综合结果就是[0, 31] = true;其他都是false; 

    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 thingreturn  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 is deprecated for non-system apps. For system apps, this type should be// in a higher layer than TYPE_APPLICATION_OVERLAY.return  canAddInternalSystemWindow ? 12 : 9;case TYPE_APPLICATION_OVERLAY:return  11;case TYPE_INPUT_METHOD:// on-screen keyboards and other such input method user interfaces go here.return  13;case TYPE_INPUT_METHOD_DIALOG:// on-screen keyboards and other such input method user interfaces go here.return  14;case TYPE_STATUS_BAR:return  15;case TYPE_STATUS_BAR_ADDITIONAL:return  16;case TYPE_NOTIFICATION_SHADE:return  17;case TYPE_STATUS_BAR_SUB_PANEL:return  18;case TYPE_KEYGUARD_DIALOG:return  19;case TYPE_VOICE_INTERACTION_STARTING:return  20;case TYPE_VOICE_INTERACTION:// voice interaction layer should show above the lock screen.return  21;case TYPE_VOLUME_OVERLAY:// the on-screen volume indicator and controller shown when the user// changes the device volumereturn  22;case TYPE_SYSTEM_OVERLAY:// the on-screen volume indicator and controller shown when the user// changes the device volumereturn  canAddInternalSystemWindow ? 23 : 10;case TYPE_NAVIGATION_BAR:// the navigation bar, if available, shows atop most thingsreturn  24;case TYPE_NAVIGATION_BAR_PANEL:// some panels (e.g. search) need to show on top of the navigation barreturn  25;case TYPE_SCREENSHOT:// screenshot selection layer shouldn't go above system error, but it should cover// navigation bars at the very least.return  26;case TYPE_SYSTEM_ERROR:// system-level error dialogsreturn  canAddInternalSystemWindow ? 27 : 9;case TYPE_MAGNIFICATION_OVERLAY:// used to highlight the magnified portion of a displayreturn  28;case TYPE_DISPLAY_OVERLAY:// used to simulate secondary display devicesreturn  29;case TYPE_DRAG:// the drag layer: input for drag-and-drop is associated with this window,// which sits above all other focusable windowsreturn  30;case TYPE_ACCESSIBILITY_OVERLAY:// overlay put by accessibility services to intercept user interactionreturn  31;case TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY:return 32;case TYPE_SECURE_SYSTEM_OVERLAY:return  33;case TYPE_BOOT_PROGRESS:return  34;case TYPE_POINTER:// the (mouse) pointer layerreturn  35;default:Slog.e("WindowManager", "Unknown window type: " + type);return 3;}}
02-02 19:55:04.254  3530  3530 D jinyanmeiWMS:  mName:WindowedMagnification
02-02 19:55:04.254  3530  3530 D jinyanmeiWMS:    mId:4
02-02 19:55:04.254  3530  3530 D jinyanmeiWMS:    mWindowLayers[0]:true
02-02 19:55:04.254  3530  3530 D jinyanmeiWMS:    mWindowLayers[1]:true
02-02 19:55:04.254  3530  3530 D jinyanmeiWMS:    mWindowLayers[2]:true
02-02 19:55:04.255  3530  3530 D jinyanmeiWMS:    mWindowLayers[3]:true
02-02 19:55:04.255  3530  3530 D jinyanmeiWMS:    mWindowLayers[4]:true
02-02 19:55:04.255  3530  3530 D jinyanmeiWMS:    mWindowLayers[5]:true
02-02 19:55:04.255  3530  3530 D jinyanmeiWMS:    mWindowLayers[6]:true
02-02 19:55:04.255  3530  3530 D jinyanmeiWMS:    mWindowLayers[7]:true
02-02 19:55:04.255  3530  3530 D jinyanmeiWMS:    mWindowLayers[8]:true
02-02 19:55:04.255  3530  3530 D jinyanmeiWMS:    mWindowLayers[9]:true
02-02 19:55:04.255  3530  3530 D jinyanmeiWMS:    mWindowLayers[10]:true
02-02 19:55:04.255  3530  3530 D jinyanmeiWMS:    mWindowLayers[11]:true
02-02 19:55:04.255  3530  3530 D jinyanmeiWMS:    mWindowLayers[12]:true
02-02 19:55:04.255  3530  3530 D jinyanmeiWMS:    mWindowLayers[13]:true
02-02 19:55:04.255  3530  3530 D jinyanmeiWMS:    mWindowLayers[14]:true
02-02 19:55:04.256  3530  3530 D jinyanmeiWMS:    mWindowLayers[15]:true
02-02 19:55:04.256  3530  3530 D jinyanmeiWMS:    mWindowLayers[16]:true
02-02 19:55:04.256  3530  3530 D jinyanmeiWMS:    mWindowLayers[17]:true
02-02 19:55:04.256  3530  3530 D jinyanmeiWMS:    mWindowLayers[18]:true
02-02 19:55:04.256  3530  3530 D jinyanmeiWMS:    mWindowLayers[19]:true
02-02 19:55:04.256  3530  3530 D jinyanmeiWMS:    mWindowLayers[20]:true
02-02 19:55:04.256  3530  3530 D jinyanmeiWMS:    mWindowLayers[21]:true
02-02 19:55:04.256  3530  3530 D jinyanmeiWMS:    mWindowLayers[22]:true
02-02 19:55:04.256  3530  3530 D jinyanmeiWMS:    mWindowLayers[23]:true
02-02 19:55:04.256  3530  3530 D jinyanmeiWMS:    mWindowLayers[24]:true
02-02 19:55:04.256  3530  3530 D jinyanmeiWMS:    mWindowLayers[25]:true
02-02 19:55:04.256  3530  3530 D jinyanmeiWMS:    mWindowLayers[26]:true
02-02 19:55:04.257  3530  3530 D jinyanmeiWMS:    mWindowLayers[27]:true
02-02 19:55:04.257  3530  3530 D jinyanmeiWMS:    mWindowLayers[28]:true
02-02 19:55:04.257  3530  3530 D jinyanmeiWMS:    mWindowLayers[29]:true
02-02 19:55:04.257  3530  3530 D jinyanmeiWMS:    mWindowLayers[30]:true
02-02 19:55:04.257  3530  3530 D jinyanmeiWMS:    mWindowLayers[31]:true
02-02 19:55:04.257  3530  3530 D jinyanmeiWMS:    mWindowLayers[32]:false
02-02 19:55:04.257  3530  3530 D jinyanmeiWMS:    mWindowLayers[33]:false
02-02 19:55:04.257  3530  3530 D jinyanmeiWMS:    mWindowLayers[34]:false
02-02 19:55:04.257  3530  3530 D jinyanmeiWMS:    mWindowLayers[35]:false
02-02 19:55:04.257  3530  3530 D jinyanmeiWMS:    mWindowLayers[36]:false
02-02 19:55:04.271  3530  3530 D jinyanmeiWMS:  mName:HideDisplayCutout
02-02 19:55:04.271  3530  3530 D jinyanmeiWMS:    mId:6
02-02 19:55:04.271  3530  3530 D jinyanmeiWMS:    mWindowLayers[0]:true
02-02 19:55:04.271  3530  3530 D jinyanmeiWMS:    mWindowLayers[1]:true
02-02 19:55:04.271  3530  3530 D jinyanmeiWMS:    mWindowLayers[2]:true
02-02 19:55:04.271  3530  3530 D jinyanmeiWMS:    mWindowLayers[3]:true
02-02 19:55:04.272  3530  3530 D jinyanmeiWMS:    mWindowLayers[4]:true
02-02 19:55:04.272  3530  3530 D jinyanmeiWMS:    mWindowLayers[5]:true
02-02 19:55:04.272  3530  3530 D jinyanmeiWMS:    mWindowLayers[6]:true
02-02 19:55:04.272  3530  3530 D jinyanmeiWMS:    mWindowLayers[7]:true
02-02 19:55:04.272  3530  3530 D jinyanmeiWMS:    mWindowLayers[8]:true
02-02 19:55:04.272  3530  3530 D jinyanmeiWMS:    mWindowLayers[9]:true
02-02 19:55:04.272  3530  3530 D jinyanmeiWMS:    mWindowLayers[10]:true
02-02 19:55:04.272  3530  3530 D jinyanmeiWMS:    mWindowLayers[11]:true
02-02 19:55:04.272  3530  3530 D jinyanmeiWMS:    mWindowLayers[12]:true
02-02 19:55:04.272  3530  3530 D jinyanmeiWMS:    mWindowLayers[13]:true
02-02 19:55:04.272  3530  3530 D jinyanmeiWMS:    mWindowLayers[14]:true
02-02 19:55:04.272  3530  3530 D jinyanmeiWMS:    mWindowLayers[15]:false
02-02 19:55:04.273  3530  3530 D jinyanmeiWMS:    mWindowLayers[16]:true
02-02 19:55:04.273  3530  3530 D jinyanmeiWMS:    mWindowLayers[17]:false
02-02 19:55:04.273  3530  3530 D jinyanmeiWMS:    mWindowLayers[18]:true
02-02 19:55:04.273  3530  3530 D jinyanmeiWMS:    mWindowLayers[19]:true
02-02 19:55:04.273  3530  3530 D jinyanmeiWMS:    mWindowLayers[20]:true
02-02 19:55:04.273  3530  3530 D jinyanmeiWMS:    mWindowLayers[21]:true
02-02 19:55:04.273  3530  3530 D jinyanmeiWMS:    mWindowLayers[22]:true
02-02 19:55:04.273  3530  3530 D jinyanmeiWMS:    mWindowLayers[23]:true
02-02 19:55:04.273  3530  3530 D jinyanmeiWMS:    mWindowLayers[24]:false
02-02 19:55:04.273  3530  3530 D jinyanmeiWMS:    mWindowLayers[25]:false
02-02 19:55:04.273  3530  3530 D jinyanmeiWMS:    mWindowLayers[26]:true
02-02 19:55:04.273  3530  3530 D jinyanmeiWMS:    mWindowLayers[27]:true
02-02 19:55:04.273  3530  3530 D jinyanmeiWMS:    mWindowLayers[28]:true
02-02 19:55:04.273  3530  3530 D jinyanmeiWMS:    mWindowLayers[29]:true
02-02 19:55:04.273  3530  3530 D jinyanmeiWMS:    mWindowLayers[30]:true
02-02 19:55:04.273  3530  3530 D jinyanmeiWMS:    mWindowLayers[31]:true
02-02 19:55:04.273  3530  3530 D jinyanmeiWMS:    mWindowLayers[32]:true
02-02 19:55:04.273  3530  3530 D jinyanmeiWMS:    mWindowLayers[33]:true
02-02 19:55:04.273  3530  3530 D jinyanmeiWMS:    mWindowLayers[34]:true
02-02 19:55:04.273  3530  3530 D jinyanmeiWMS:    mWindowLayers[35]:true
02-02 19:55:04.273  3530  3530 D jinyanmeiWMS:    mWindowLayers[36]:false
02-02 19:55:04.282  3530  3530 D jinyanmeiWMS:  mName:OneHanded
02-02 19:55:04.282  3530  3530 D jinyanmeiWMS:    mId:3
02-02 19:55:04.282  3530  3530 D jinyanmeiWMS:    mWindowLayers[0]:true
02-02 19:55:04.282  3530  3530 D jinyanmeiWMS:    mWindowLayers[1]:true
02-02 19:55:04.282  3530  3530 D jinyanmeiWMS:    mWindowLayers[2]:true
02-02 19:55:04.282  3530  3530 D jinyanmeiWMS:    mWindowLayers[3]:true
02-02 19:55:04.282  3530  3530 D jinyanmeiWMS:    mWindowLayers[4]:true
02-02 19:55:04.282  3530  3530 D jinyanmeiWMS:    mWindowLayers[5]:true
02-02 19:55:04.282  3530  3530 D jinyanmeiWMS:    mWindowLayers[6]:true
02-02 19:55:04.282  3530  3530 D jinyanmeiWMS:    mWindowLayers[7]:true
02-02 19:55:04.282  3530  3530 D jinyanmeiWMS:    mWindowLayers[8]:true
02-02 19:55:04.282  3530  3530 D jinyanmeiWMS:    mWindowLayers[9]:true
02-02 19:55:04.282  3530  3530 D jinyanmeiWMS:    mWindowLayers[10]:true
02-02 19:55:04.282  3530  3530 D jinyanmeiWMS:    mWindowLayers[11]:true
02-02 19:55:04.283  3530  3530 D jinyanmeiWMS:    mWindowLayers[12]:true
02-02 19:55:04.283  3530  3530 D jinyanmeiWMS:    mWindowLayers[13]:true
02-02 19:55:04.283  3530  3530 D jinyanmeiWMS:    mWindowLayers[14]:true
02-02 19:55:04.283  3530  3530 D jinyanmeiWMS:    mWindowLayers[15]:true
02-02 19:55:04.283  3530  3530 D jinyanmeiWMS:    mWindowLayers[16]:true
02-02 19:55:04.283  3530  3530 D jinyanmeiWMS:    mWindowLayers[17]:true
02-02 19:55:04.283  3530  3530 D jinyanmeiWMS:    mWindowLayers[18]:true
02-02 19:55:04.283  3530  3530 D jinyanmeiWMS:    mWindowLayers[19]:true
02-02 19:55:04.283  3530  3530 D jinyanmeiWMS:    mWindowLayers[20]:true
02-02 19:55:04.283  3530  3530 D jinyanmeiWMS:    mWindowLayers[21]:true
02-02 19:55:04.283  3530  3530 D jinyanmeiWMS:    mWindowLayers[22]:true
02-02 19:55:04.283  3530  3530 D jinyanmeiWMS:    mWindowLayers[23]:true
02-02 19:55:04.283  3530  3530 D jinyanmeiWMS:    mWindowLayers[24]:false
02-02 19:55:04.283  3530  3530 D jinyanmeiWMS:    mWindowLayers[25]:false
02-02 19:55:04.283  3530  3530 D jinyanmeiWMS:    mWindowLayers[26]:true
02-02 19:55:04.283  3530  3530 D jinyanmeiWMS:    mWindowLayers[27]:true
02-02 19:55:04.283  3530  3530 D jinyanmeiWMS:    mWindowLayers[28]:true
02-02 19:55:04.283  3530  3530 D jinyanmeiWMS:    mWindowLayers[29]:true
02-02 19:55:04.283  3530  3530 D jinyanmeiWMS:    mWindowLayers[30]:true
02-02 19:55:04.283  3530  3530 D jinyanmeiWMS:    mWindowLayers[31]:true
02-02 19:55:04.283  3530  3530 D jinyanmeiWMS:    mWindowLayers[32]:true
02-02 19:55:04.283  3530  3530 D jinyanmeiWMS:    mWindowLayers[33]:false
02-02 19:55:04.283  3530  3530 D jinyanmeiWMS:    mWindowLayers[34]:true
02-02 19:55:04.283  3530  3530 D jinyanmeiWMS:    mWindowLayers[35]:true
02-02 19:55:04.283  3530  3530 D jinyanmeiWMS:    mWindowLayers[36]:false
02-02 19:55:04.291  3530  3530 D jinyanmeiWMS:  mName:FullscreenMagnification
02-02 19:55:04.291  3530  3530 D jinyanmeiWMS:    mId:5
02-02 19:55:04.291  3530  3530 D jinyanmeiWMS:    mWindowLayers[0]:true
02-02 19:55:04.291  3530  3530 D jinyanmeiWMS:    mWindowLayers[1]:true
02-02 19:55:04.291  3530  3530 D jinyanmeiWMS:    mWindowLayers[2]:true
02-02 19:55:04.291  3530  3530 D jinyanmeiWMS:    mWindowLayers[3]:true
02-02 19:55:04.291  3530  3530 D jinyanmeiWMS:    mWindowLayers[4]:true
02-02 19:55:04.291  3530  3530 D jinyanmeiWMS:    mWindowLayers[5]:true
02-02 19:55:04.291  3530  3530 D jinyanmeiWMS:    mWindowLayers[6]:true
02-02 19:55:04.291  3530  3530 D jinyanmeiWMS:    mWindowLayers[7]:true
02-02 19:55:04.291  3530  3530 D jinyanmeiWMS:    mWindowLayers[8]:true
02-02 19:55:04.291  3530  3530 D jinyanmeiWMS:    mWindowLayers[9]:true
02-02 19:55:04.291  3530  3530 D jinyanmeiWMS:    mWindowLayers[10]:true
02-02 19:55:04.291  3530  3530 D jinyanmeiWMS:    mWindowLayers[11]:true
02-02 19:55:04.291  3530  3530 D jinyanmeiWMS:    mWindowLayers[12]:true
02-02 19:55:04.291  3530  3530 D jinyanmeiWMS:    mWindowLayers[13]:false
02-02 19:55:04.291  3530  3530 D jinyanmeiWMS:    mWindowLayers[14]:false
02-02 19:55:04.291  3530  3530 D jinyanmeiWMS:    mWindowLayers[15]:true
02-02 19:55:04.291  3530  3530 D jinyanmeiWMS:    mWindowLayers[16]:true
02-02 19:55:04.291  3530  3530 D jinyanmeiWMS:    mWindowLayers[17]:true
02-02 19:55:04.292  3530  3530 D jinyanmeiWMS:    mWindowLayers[18]:true
02-02 19:55:04.292  3530  3530 D jinyanmeiWMS:    mWindowLayers[19]:true
02-02 19:55:04.292  3530  3530 D jinyanmeiWMS:    mWindowLayers[20]:true
02-02 19:55:04.292  3530  3530 D jinyanmeiWMS:    mWindowLayers[21]:true
02-02 19:55:04.292  3530  3530 D jinyanmeiWMS:    mWindowLayers[22]:true
02-02 19:55:04.292  3530  3530 D jinyanmeiWMS:    mWindowLayers[23]:true
02-02 19:55:04.292  3530  3530 D jinyanmeiWMS:    mWindowLayers[24]:false
02-02 19:55:04.292  3530  3530 D jinyanmeiWMS:    mWindowLayers[25]:false
02-02 19:55:04.292  3530  3530 D jinyanmeiWMS:    mWindowLayers[26]:true
02-02 19:55:04.292  3530  3530 D jinyanmeiWMS:    mWindowLayers[27]:true
02-02 19:55:04.292  3530  3530 D jinyanmeiWMS:    mWindowLayers[28]:false
02-02 19:55:04.292  3530  3530 D jinyanmeiWMS:    mWindowLayers[29]:true
02-02 19:55:04.292  3530  3530 D jinyanmeiWMS:    mWindowLayers[30]:true
02-02 19:55:04.292  3530  3530 D jinyanmeiWMS:    mWindowLayers[31]:true
02-02 19:55:04.292  3530  3530 D jinyanmeiWMS:    mWindowLayers[32]:false
02-02 19:55:04.292  3530  3530 D jinyanmeiWMS:    mWindowLayers[33]:true
02-02 19:55:04.292  3530  3530 D jinyanmeiWMS:    mWindowLayers[34]:true
02-02 19:55:04.292  3530  3530 D jinyanmeiWMS:    mWindowLayers[35]:true
02-02 19:55:04.292  3530  3530 D jinyanmeiWMS:    mWindowLayers[36]:false
02-02 19:55:04.296  3530  3530 D jinyanmeiWMS:  mName:ImePlaceholder
02-02 19:55:04.296  3530  3530 D jinyanmeiWMS:    mId:7
02-02 19:55:04.296  3530  3530 D jinyanmeiWMS:    mWindowLayers[0]:false
02-02 19:55:04.296  3530  3530 D jinyanmeiWMS:    mWindowLayers[1]:false
02-02 19:55:04.296  3530  3530 D jinyanmeiWMS:    mWindowLayers[2]:false
02-02 19:55:04.296  3530  3530 D jinyanmeiWMS:    mWindowLayers[3]:false
02-02 19:55:04.296  3530  3530 D jinyanmeiWMS:    mWindowLayers[4]:false
02-02 19:55:04.296  3530  3530 D jinyanmeiWMS:    mWindowLayers[5]:false
02-02 19:55:04.296  3530  3530 D jinyanmeiWMS:    mWindowLayers[6]:false
02-02 19:55:04.296  3530  3530 D jinyanmeiWMS:    mWindowLayers[7]:false
02-02 19:55:04.296  3530  3530 D jinyanmeiWMS:    mWindowLayers[8]:false
02-02 19:55:04.296  3530  3530 D jinyanmeiWMS:    mWindowLayers[9]:false
02-02 19:55:04.296  3530  3530 D jinyanmeiWMS:    mWindowLayers[10]:false
02-02 19:55:04.296  3530  3530 D jinyanmeiWMS:    mWindowLayers[11]:false
02-02 19:55:04.296  3530  3530 D jinyanmeiWMS:    mWindowLayers[12]:false
02-02 19:55:04.296  3530  3530 D jinyanmeiWMS:    mWindowLayers[13]:true
02-02 19:55:04.297  3530  3530 D jinyanmeiWMS:    mWindowLayers[14]:true
02-02 19:55:04.297  3530  3530 D jinyanmeiWMS:    mWindowLayers[15]:false
02-02 19:55:04.297  3530  3530 D jinyanmeiWMS:    mWindowLayers[16]:false
02-02 19:55:04.297  3530  3530 D jinyanmeiWMS:    mWindowLayers[17]:false
02-02 19:55:04.297  3530  3530 D jinyanmeiWMS:    mWindowLayers[18]:false
02-02 19:55:04.297  3530  3530 D jinyanmeiWMS:    mWindowLayers[19]:false
02-02 19:55:04.297  3530  3530 D jinyanmeiWMS:    mWindowLayers[20]:false
02-02 19:55:04.297  3530  3530 D jinyanmeiWMS:    mWindowLayers[21]:false
02-02 19:55:04.297  3530  3530 D jinyanmeiWMS:    mWindowLayers[22]:false
02-02 19:55:04.297  3530  3530 D jinyanmeiWMS:    mWindowLayers[23]:false
02-02 19:55:04.297  3530  3530 D jinyanmeiWMS:    mWindowLayers[24]:false
02-02 19:55:04.297  3530  3530 D jinyanmeiWMS:    mWindowLayers[25]:false
02-02 19:55:04.297  3530  3530 D jinyanmeiWMS:    mWindowLayers[26]:false
02-02 19:55:04.297  3530  3530 D jinyanmeiWMS:    mWindowLayers[27]:false
02-02 19:55:04.297  3530  3530 D jinyanmeiWMS:    mWindowLayers[28]:false
02-02 19:55:04.297  3530  3530 D jinyanmeiWMS:    mWindowLayers[29]:false
02-02 19:55:04.298  3530  3530 D jinyanmeiWMS:    mWindowLayers[30]:false
02-02 19:55:04.298  3530  3530 D jinyanmeiWMS:    mWindowLayers[31]:false
02-02 19:55:04.298  3530  3530 D jinyanmeiWMS:    mWindowLayers[32]:false
02-02 19:55:04.298  3530  3530 D jinyanmeiWMS:    mWindowLayers[33]:false
02-02 19:55:04.298  3530  3530 D jinyanmeiWMS:    mWindowLayers[34]:false
02-02 19:55:04.298  3530  3530 D jinyanmeiWMS:    mWindowLayers[35]:false
02-02 19:55:04.298  3530  3530 D jinyanmeiWMS:    mWindowLayers[36]:false

4. 生成DisplayArea层级结构

    Result build(WindowManagerService wmService) {validate();Slog.v("jinyanmeiWMS", "DisplayAreaPolicyBuilder wmService " + wmService, new RuntimeException("jinyanmeiWMS"));// Attach DA group roots to screen hierarchy before adding windows to group hierarchies.mRootHierarchyBuilder.build(mDisplayAreaGroupHierarchyBuilders);List<RootDisplayArea> displayAreaGroupRoots = new ArrayList<>(mDisplayAreaGroupHierarchyBuilders.size());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);}
        private void build(@Nullable List<HierarchyBuilder> displayAreaGroupHierarchyBuilders) {final WindowManagerPolicy policy = mRoot.mWmService.mPolicy;final int maxWindowLayerCount = policy.getMaxWindowLayer() + 1;final DisplayArea.Tokens[] displayAreaForLayer =new DisplayArea.Tokens[maxWindowLayerCount];final Map<Feature, List<DisplayArea<WindowContainer>>> featureAreas =new ArrayMap<>(mFeatures.size());Slog.v("jinyanmeiWMS", "DisplayAreaPolicyBuilder maxWindowLayerCount "  + maxWindowLayerCount);Slog.v("jinyanmeiWMS", "DisplayAreaPolicyBuilder build " , new RuntimeException("jinyanmeiWMS"));for (int i = 0; i < mFeatures.size(); i++) {Slog.v("jinyanmeiWMS", "DisplayAreaPolicyBuilder mFeatures.get(i) "  + mFeatures.get(i));featureAreas.put(mFeatures.get(i), new ArrayList<>());}// This method constructs the layer hierarchy with the following properties:// (1) Every feature maps to a set of DisplayAreas// (2) After adding a window, for every feature the window's type belongs to,//     it is a descendant of one of the corresponding DisplayAreas of the feature.// (3) Z-order is maintained, i.e. if z-range(area) denotes the set of layers of windows//     within a DisplayArea://      for every pair of DisplayArea siblings (a,b), where a is below b, it holds that//      max(z-range(a)) <= min(z-range(b))//// The algorithm below iteratively creates such a hierarchy://  - Initially, all windows are attached to the root.//  - For each feature we create a set of DisplayAreas, by looping over the layers//    - if the feature does apply to the current layer, we need to find a DisplayArea//      for it to satisfy (2)//      - we can re-use the previous layer's area if://         the current feature also applies to the previous layer, (to satisfy (3))//         and the last feature that applied to the previous layer is the same as//           the last feature that applied to the current layer (to satisfy (2))//      - otherwise we create a new DisplayArea below the last feature that applied//        to the current layerPendingArea[] areaForLayer = new PendingArea[maxWindowLayerCount];final PendingArea root = new PendingArea(null, 0, null);Arrays.fill(areaForLayer, root);// Create DisplayAreas to cover all defined features.final int size = mFeatures.size();for (int i = 0; i < size; i++) {// Traverse the features with the order they are defined, so that the early defined// feature will be on the top in the hierarchy.final Feature feature = mFeatures.get(i);Slog.v("jinyanmeiWMS", "DisplayAreaPolicyBuilder feature[" + i + "]:"  + feature);PendingArea featureArea = null;for (int layer = 0; layer < maxWindowLayerCount; layer++) {if (feature.mWindowLayers[layer]) {// This feature will be applied to this window layer.//// We need to find a DisplayArea for it:// We can reuse the existing one if it was created for this feature for the// previous layer AND the last feature that applied to the previous layer is// the same as the feature that applied to the current layer (so they are ok// to share the same parent DisplayArea).if (featureArea == null || featureArea.mParent != areaForLayer[layer]) {// No suitable DisplayArea:// Create a new one under the previous area (as parent) for this layer.featureArea = new PendingArea(feature, layer, areaForLayer[layer]);areaForLayer[layer].mChildren.add(featureArea);}areaForLayer[layer] = featureArea;} else {// This feature won't be applied to this window layer. If it needs to be// applied to the next layer, we will need to create a new DisplayArea for// that.featureArea = null;}Slog.v("jinyanmeiWMS", "                DisplayAreaPolicyBuilder areaForLayer[" + layer + "]:"  + areaForLayer[layer]);}}// Create Tokens as leaf for every layer.PendingArea leafArea = null;int leafType = LEAF_TYPE_TOKENS;for (int layer = 0; layer < maxWindowLayerCount; layer++) {int type = typeOfLayer(policy, layer);Slog.v("jinyanmeiWMS", "    layer:" + layer + "            type:"  + type);// Check whether we can reuse the same Tokens with the previous layer. This happens// if the previous layer is the same type as the current layer AND there is no// feature that applies to only one of them.if (leafArea == null || leafArea.mParent != areaForLayer[layer]|| type != leafType) {// Create a new Tokens for this layer.leafArea = new PendingArea(null /* feature */, layer, areaForLayer[layer]);areaForLayer[layer].mChildren.add(leafArea);Slog.v("jinyanmeiWMS", "    areaForLayer[layer]:" + areaForLayer[layer]);for (PendingArea x: areaForLayer[layer].mChildren)Slog.v("jinyanmeiWMS", "   areaForLayer[layer].mChildren:" + x);leafType = type;if (leafType == LEAF_TYPE_TASK_CONTAINERS) {// We use the passed in TaskDisplayAreas for task container type of layer.// Skip creating Tokens even if there is no TDA.addTaskDisplayAreasToApplicationLayer(areaForLayer[layer]);addDisplayAreaGroupsToApplicationLayer(areaForLayer[layer],displayAreaGroupHierarchyBuilders);leafArea.mSkipTokens = true;} else if (leafType == LEAF_TYPE_IME_CONTAINERS) {// We use the passed in ImeContainer for ime container type of layer.// Skip creating Tokens even if there is no ime container.leafArea.mExisting = mImeContainer;leafArea.mSkipTokens = true;}}leafArea.mMaxLayer = layer;}root.computeMaxLayer();// We built a tree of PendingAreas above with all the necessary info to represent the// hierarchy, now create and attach real DisplayAreas to the root.root.instantiateChildren(mRoot, displayAreaForLayer, 0, featureAreas);// Notify the root that we have finished attaching all the DisplayAreas. Cache all the// feature related collections there for fast access.mRoot.onHierarchyBuilt(mFeatures, displayAreaForLayer, featureAreas);}
        void instantiateChildren(DisplayArea<DisplayArea> parent, DisplayArea.Tokens[] areaForLayer,int level, Map<Feature, List<DisplayArea<WindowContainer>>> areas) {mChildren.sort(Comparator.comparingInt(pendingArea -> pendingArea.mMinLayer));Slog.v("jinyanmeiWMS", "instantiateChildren ===============");Slog.v("jinyanmeiWMS", "instantiateChildren   mChildren:" + mChildren.size());Slog.v("jinyanmeiWMS", "instantiateChildren   level:" + level);for (int i = 0; i < mChildren.size(); i++) {final PendingArea child = mChildren.get(i);Slog.v("jinyanmeiWMS", "instantiateChildren   child[" + i + "]:" + child);final DisplayArea area = child.createArea(parent, areaForLayer);Slog.v("jinyanmeiWMS", "instantiateChildren   area:" + area);if (area == null) {// TaskDisplayArea and ImeContainer can be set at different hierarchy, so it can// be null.continue;}Slog.v("jinyanmeiWMS", "instantiateChildren   parent:" + parent);parent.addChild(area, WindowContainer.POSITION_TOP);Slog.v("jinyanmeiWMS", "instantiateChildren   child.mFeature:" + child.mFeature);if (child.mFeature != null) {areas.get(child.mFeature).add(area);}child.instantiateChildren(area, areaForLayer, level + 1, areas);}}
        private void build(@Nullable List<HierarchyBuilder> displayAreaGroupHierarchyBuilders) {final WindowManagerPolicy policy = mRoot.mWmService.mPolicy;final int maxWindowLayerCount = policy.getMaxWindowLayer() + 1;final DisplayArea.Tokens[] displayAreaForLayer =new DisplayArea.Tokens[maxWindowLayerCount];final Map<Feature, List<DisplayArea<WindowContainer>>> featureAreas =new ArrayMap<>(mFeatures.size());Slog.v("jinyanmeiWMS", "DisplayAreaPolicyBuilder maxWindowLayerCount "  + maxWindowLayerCount);Slog.v("jinyanmeiWMS", "DisplayAreaPolicyBuilder build " , new RuntimeException("jinyanmeiWMS"));for (int i = 0; i < mFeatures.size(); i++) {Slog.v("jinyanmeiWMS", "DisplayAreaPolicyBuilder mFeatures.get(i) "  + mFeatures.get(i));featureAreas.put(mFeatures.get(i), new ArrayList<>());}// This method constructs the layer hierarchy with the following properties:// (1) Every feature maps to a set of DisplayAreas// (2) After adding a window, for every feature the window's type belongs to,//     it is a descendant of one of the corresponding DisplayAreas of the feature.// (3) Z-order is maintained, i.e. if z-range(area) denotes the set of layers of windows//     within a DisplayArea://      for every pair of DisplayArea siblings (a,b), where a is below b, it holds that//      max(z-range(a)) <= min(z-range(b))//// The algorithm below iteratively creates such a hierarchy://  - Initially, all windows are attached to the root.//  - For each feature we create a set of DisplayAreas, by looping over the layers//    - if the feature does apply to the current layer, we need to find a DisplayArea//      for it to satisfy (2)//      - we can re-use the previous layer's area if://         the current feature also applies to the previous layer, (to satisfy (3))//         and the last feature that applied to the previous layer is the same as//           the last feature that applied to the current layer (to satisfy (2))//      - otherwise we create a new DisplayArea below the last feature that applied//        to the current layerPendingArea[] areaForLayer = new PendingArea[maxWindowLayerCount];final PendingArea root = new PendingArea(null, 0, null);Arrays.fill(areaForLayer, root);// Create DisplayAreas to cover all defined features.final int size = mFeatures.size();for (int i = 0; i < size; i++) {// Traverse the features with the order they are defined, so that the early defined// feature will be on the top in the hierarchy.final Feature feature = mFeatures.get(i);Slog.v("jinyanmeiWMS", "DisplayAreaPolicyBuilder feature[" + i + "]:"  + feature);PendingArea featureArea = null;for (int layer = 0; layer < maxWindowLayerCount; layer++) {if (feature.mWindowLayers[layer]) {// This feature will be applied to this window layer.//// We need to find a DisplayArea for it:// We can reuse the existing one if it was created for this feature for the// previous layer AND the last feature that applied to the previous layer is// the same as the feature that applied to the current layer (so they are ok// to share the same parent DisplayArea).if (featureArea == null || featureArea.mParent != areaForLayer[layer]) {// No suitable DisplayArea:// Create a new one under the previous area (as parent) for this layer.featureArea = new PendingArea(feature, layer, areaForLayer[layer]);areaForLayer[layer].mChildren.add(featureArea);}areaForLayer[layer] = featureArea;} else {// This feature won't be applied to this window layer. If it needs to be// applied to the next layer, we will need to create a new DisplayArea for// that.featureArea = null;}Slog.v("jinyanmeiWMS", "                DisplayAreaPolicyBuilder areaForLayer[" + layer + "]:"  + areaForLayer[layer]);}}// Create Tokens as leaf for every layer.PendingArea leafArea = null;int leafType = LEAF_TYPE_TOKENS;for (int layer = 0; layer < maxWindowLayerCount; layer++) {int type = typeOfLayer(policy, layer);Slog.v("jinyanmeiWMS", "    layer:" + layer + "            type:"  + type);// Check whether we can reuse the same Tokens with the previous layer. This happens// if the previous layer is the same type as the current layer AND there is no// feature that applies to only one of them.if (leafArea == null || leafArea.mParent != areaForLayer[layer]|| type != leafType) {// Create a new Tokens for this layer.leafArea = new PendingArea(null /* feature */, layer, areaForLayer[layer]);areaForLayer[layer].mChildren.add(leafArea);Slog.v("jinyanmeiWMS", "    areaForLayer[:" + layer + "]:" + areaForLayer[layer]);for (PendingArea x: areaForLayer[layer].mChildren)Slog.v("jinyanmeiWMS", "  areaForLayer[:" + layer + "]:" + ".children:" + x);leafType = type;if (leafType == LEAF_TYPE_TASK_CONTAINERS) {// We use the passed in TaskDisplayAreas for task container type of layer.// Skip creating Tokens even if there is no TDA.addTaskDisplayAreasToApplicationLayer(areaForLayer[layer]);addDisplayAreaGroupsToApplicationLayer(areaForLayer[layer],displayAreaGroupHierarchyBuilders);leafArea.mSkipTokens = true;} else if (leafType == LEAF_TYPE_IME_CONTAINERS) {// We use the passed in ImeContainer for ime container type of layer.// Skip creating Tokens even if there is no ime container.leafArea.mExisting = mImeContainer;leafArea.mSkipTokens = true;}}leafArea.mMaxLayer = layer;}root.computeMaxLayer();// We built a tree of PendingAreas above with all the necessary info to represent the// hierarchy, now create and attach real DisplayAreas to the root.root.instantiateChildren(mRoot, displayAreaForLayer, 0, featureAreas);// Notify the root that we have finished attaching all the DisplayAreas. Cache all the// feature related collections there for fast access.mRoot.onHierarchyBuilt(mFeatures, displayAreaForLayer, featureAreas);}
instantiateChildren
912  
913          void instantiateChildren(DisplayArea<DisplayArea> parent, DisplayArea.Tokens[] areaForLayer,
914                  int level, Map<Feature, List<DisplayArea<WindowContainer>>> areas) {
915              mChildren.sort(Comparator.comparingInt(pendingArea -> pendingArea.mMinLayer));
916              for (int i = 0; i < mChildren.size(); i++) {
917                  final PendingArea child = mChildren.get(i);
918                  final DisplayArea area = child.createArea(parent, areaForLayer);
919                  if (area == null) {
920                      // TaskDisplayArea and ImeContainer can be set at different hierarchy, so it can
921                      // be null.
922                      continue;
923                  }
924                  parent.addChild(area, WindowContainer.POSITION_TOP);
925                  if (child.mFeature != null) {
926                      areas.get(child.mFeature).add(area);
927                  }
928                  child.instantiateChildren(area, areaForLayer, level + 1, areas);
929              }
930          }

把child排下序

为每个chanild创建DisplayArea 

933          private DisplayArea createArea(DisplayArea<DisplayArea> parent,
934                  DisplayArea.Tokens[] areaForLayer) {
935              if (mExisting != null) {
936                  if (mExisting.asTokens() != null) {
937                      // Store the WindowToken container for layers
938                      fillAreaForLayers(mExisting.asTokens(), areaForLayer);
939                  }
940                  return mExisting;
941              }
942              if (mSkipTokens) {
943                  return null;
944              }
945              DisplayArea.Type type;
946              if (mMinLayer > APPLICATION_LAYER) {
947                  type = DisplayArea.Type.ABOVE_TASKS;
948              } else if (mMaxLayer < APPLICATION_LAYER) {
949                  type = DisplayArea.Type.BELOW_TASKS;
950              } else {
951                  type = DisplayArea.Type.ANY;
952              }
953              if (mFeature == null) {
954                  final DisplayArea.Tokens leaf = new DisplayArea.Tokens(parent.mWmService, type,
955                          "Leaf:" + mMinLayer + ":" + mMaxLayer);
956                  fillAreaForLayers(leaf, areaForLayer);
957                  return leaf;
958              } else {
959                  return mFeature.mNewDisplayAreaSupplier.create(parent.mWmService, type,
960                          mFeature.mName + ":" + mMinLayer + ":" + mMaxLayer, mFeature.mId);
961              }
962          }806      enum Type {
807          /** Can only contain WindowTokens above the APPLICATION_LAYER. */
808          ABOVE_TASKS,
809          /** Can only contain WindowTokens below the APPLICATION_LAYER. */
810          BELOW_TASKS,
811          /** Can contain anything. */
812          ANY;187      int APPLICATION_LAYER = 2;
188      int APPLICATION_MEDIA_SUBLAYER = -2;
189      int APPLICATION_MEDIA_OVERLAY_SUBLAYER = -1;
190      int APPLICATION_PANEL_SUBLAYER = 1;
191      int APPLICATION_SUB_PANEL_SUBLAYER = 2;
192      int APPLICATION_ABOVE_SUB_PANEL_SUBLAYER = 3;

可见DisplayArea的type有三种
806      enum Type {
807          /** Can only contain WindowTokens above the APPLICATION_LAYER. */
808          ABOVE_TASKS,
809          /** Can only contain WindowTokens below the APPLICATION_LAYER. */
810          BELOW_TASKS,
811          /** Can contain anything. */
812          ANY;

最终生成的结果

ACTIVITY MANAGER CONTAINERS (dumpsys activity containers)                                                                                                                                                        ROOT type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                                                    #0 Display 0 name="内置屏幕" type=undefined mode=fullscreen override-mode=fullscreen requested-bounds=[0,0][1080,2520] bounds=[0,0][1080,2520]                                                                    #2 Leaf:36:36 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                                          #1 WindowToken{ff2bc0c type=2024 android.os.BinderProxy@d75fb5e} type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                       #0 79280a4 ScreenDecorOverlayBottom type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                  #0 WindowToken{47c8650 type=2024 android.os.BinderProxy@89ac4d} type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                        #0 337f28b ScreenDecorOverlay type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                       #1 HideDisplayCutout:32:35 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                             #2 OneHanded:34:35 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                                     #0 FullscreenMagnification:34:35 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                       #0 Leaf:34:35 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                                       #1 FullscreenMagnification:33:33 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                       #0 Leaf:33:33 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                                        #0 OneHanded:32:32 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                                     #0 Leaf:32:32 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                                       #0 WindowedMagnification:0:31 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                          #6 HideDisplayCutout:26:31 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                             #0 OneHanded:26:31 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                                     #2 FullscreenMagnification:29:31 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                       #0 Leaf:29:31 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                                        #1 Leaf:28:28 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                                         #0 FullscreenMagnification:26:27 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                       #0 Leaf:26:27 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                                      #5 Leaf:24:25 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                                          #0 WindowToken{952a908 type=2019 android.os.BinderProxy@a354bf0} type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                       #0 5eb9120 NavigationBar0 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                           #4 HideDisplayCutout:18:23 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                             #0 OneHanded:18:23 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                                     #0 FullscreenMagnification:18:23 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                       #0 Leaf:18:23 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                                      #3 OneHanded:17:17 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                                     #0 FullscreenMagnification:17:17 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                       #0 Leaf:17:17 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                                          #0 WindowToken{202d499 type=2040 android.os.BinderProxy@a12c812} type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                       #0 a5624f8 NotificationShade type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                      #2 HideDisplayCutout:16:16 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                             #0 OneHanded:16:16 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                                     #0 FullscreenMagnification:16:16 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                       #0 Leaf:16:16 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                                      #1 OneHanded:15:15 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                                     #0 FullscreenMagnification:15:15 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                       #0 Leaf:15:15 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                                          #0 WindowToken{f0e38b1 type=2000 android.os.BinderProxy@1cac2ca} type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                       #0 aa3cc0f StatusBar type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                              #0 HideDisplayCutout:0:14 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                              #0 OneHanded:0:14 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                                      #1 ImePlaceholder:13:14 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                                #0 ImeContainer type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                                        #0 WindowToken{b203378 type=2011 android.os.Binder@9e803bf} type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                            #0 11ef791 InputMethod type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                             #0 FullscreenMagnification:0:12 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                        #2 Leaf:3:12 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                                           #0 WindowToken{6efb42e type=2038 android.os.BinderProxy@6fbe96e} type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                       #0 f4310ea ShellDropTarget type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                          #1 DefaultTaskDisplayArea type=undefined mode=fullscreen override-mode=fullscreen requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                             #1 Task=1 type=home mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                                                   #0 Task=12 type=home mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                                                  #0 ActivityRecord{e467dfb u0 com.android.launcher3/.uioverrides.QuickstepLauncher t12} type=home mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                      #0 25021f4 com.android.launcher3/com.android.launcher3.uioverrides.QuickstepLauncher type=home mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                    #0 Task=2 type=undefined mode=fullscreen override-mode=fullscreen requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                                             #1 Task=4 type=undefined mode=multi-window override-mode=multi-window requested-bounds=[0,2160][1916,3240] bounds=[0,2160][1916,3240]                                                                            #0 Task=3 type=undefined mode=multi-window override-mode=multi-window requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                                      #0 Leaf:0:1 type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                                                                            #0 WallpaperWindowToken{eeb8545 token=android.os.Binder@8f58d8e} type=undefined mode=fullscreen override-mode=fullscreen requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]                                      #0 75b90fe com.android.systemui.wallpapers.ImageWallpaper type=undefined mode=fullscreen override-mode=undefined requested-bounds=[0,0][0,0] bounds=[0,0][1080,2520]  
  • DisplayArea层级结构中的每一个DisplayArea,都包含着一个层级值范围,这个层级值范围表明了这个DisplayArea可以容纳哪些类型的窗口。

  • 然后在addWindow时候就可以根据对应的窗口的类型把widnow放在合适的位置上了, 可以参考

  • Android14 WMS-添加窗口的过程-CSDN博客