网站设计建设公司需要什么资质,全国企业信用信息公示系统查询入口,凡科网站投票排行榜是怎么做的,wordpress下载5.0.3如何通过dump中的内容找到对应的代码#xff1f; 我们dump窗口层级发现会有很多信息#xff0c;adb shell dumpsys activity containers 这里我们以其中的DefaultTaskDisplayArea为例
在源码的framework目录下查找该字符串#xff0c;找到对应的代码就可以通过打印堆栈或者…如何通过dump中的内容找到对应的代码 我们dump窗口层级发现会有很多信息adb shell dumpsys activity containers 这里我们以其中的DefaultTaskDisplayArea为例
在源码的framework目录下查找该字符串找到对应的代码就可以通过打印堆栈或者搜索代码跟踪的方式找到其调用逻辑
final TaskDisplayArea defaultTaskDisplayArea new TaskDisplayArea(content, wmService,DefaultTaskDisplayArea, FEATURE_DEFAULT_TASK_CONTAINER);也就是这一句
当然我们上篇文章也讲到了DisplayContent代表的屏幕的DisplayArea层级结构的根节点我们可以直接从DisplayContent.java的构造方法出发追踪其流程
DisplayContent初始化
代码路径/frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java
/*** Create new {link DisplayContent} instance, add itself to the root window container and* initialize direct children.* param display May not be null.* param root {link RootWindowContainer}*/DisplayContent(Display display, RootWindowContainer root) {super(root.mWindowManager, DisplayContent, FEATURE_ROOT);......final Transaction pendingTransaction getPendingTransaction();configureSurfaces(pendingTransaction);pendingTransaction.apply();......}创建新的DisplayContent实例将其自身添加到根窗口容器并初始化直接子级这里我主要关注一下configureSurfaces(pendingTransaction); /*** Configures the surfaces hierarchy for DisplayContent* This method always recreates the main surface control but reparents the children* if they are already created.* param transaction as part of which to perform the configuration*/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);}......}通过DisplayContent来配置图层结构
DisplayAreaPolicy初始化
代码路径/frameworks/base/services/core/java/com/android/server/wm/DisplayAreaPolicy.java
mDisplayAreaPolicy mWmService.getDisplayAreaPolicyProvider().instantiate(mWmService, this /* content */, this /* root */,mImeWindowsContainer)调用DisplayAreaPolicy中的Provider接口instantiate方法去初始化一个DisplayArea层级结构 记住这边传递的参数后面代码需要结合起来看
DisplayAreaPolicy.Provider /*** Provider for {link DisplayAreaPolicy} instances.** pBy implementing this interface and overriding the* {code config_deviceSpecificDisplayAreaPolicyProvider}, a device-specific implementations* of {link DisplayAreaPolicy} can be supplied.*/public interface Provider {/*** Instantiates a new {link DisplayAreaPolicy}. It should set up the {link DisplayArea}* hierarchy.** see DisplayAreaPolicy#DisplayAreaPolicy*/DisplayAreaPolicy instantiate(WindowManagerService wmService, DisplayContent content,RootDisplayArea root, DisplayArea.Tokens imeContainer);用来实例化一个DisplayAreaPolicy对象这个对象应该建立起DisplayArea层级结构实际走到的则是DisplayAreaPolicy.Provider的实现类DisplayAreaPolicy.DefaultProvider.instantiate方法
DisplayAreaPolicy.DefaultProvider /** 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) {//1.创建一个名为“DefaultTaskDisplayArea”的TaskDisplayArea,并将其添加到List中final TaskDisplayArea defaultTaskDisplayArea new TaskDisplayArea(content, wmService,DefaultTaskDisplayArea, FEATURE_DEFAULT_TASK_CONTAINER);final ListTaskDisplayArea 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.//2.创建HierarchyBuilderfinal HierarchyBuilder rootHierarchy new HierarchyBuilder(root);// Set the essential containers (even if the display doesnt support IME).//3.1添加ImeContainer到HierarchyBuilder//3.2创建并保存默认TaskDisplayArea到HierarchyBuilderrootHierarchy.setImeContainer(imeContainer).setTaskDisplayAreas(tdaList);if (content.isTrusted()) {// Only trusted display can have system decorations.//4.为HierarchyBuilder添加FeatureconfigureTrustedHierarchyBuilder(rootHierarchy, wmService, content);}// Instantiate the policy with the hierarchy defined above. This will create and attach// all the necessary DisplayAreas to the root.//5.生成DisplayArea层级结构return new DisplayAreaPolicyBuilder().setRootHierarchy(rootHierarchy).build(wmService);}这里DefaultProvider实现了这个接口。 这个方法主要干了这几件事情
1.初始化TaskDisplayArea
final TaskDisplayArea defaultTaskDisplayArea new TaskDisplayArea(content, wmService,DefaultTaskDisplayArea, FEATURE_DEFAULT_TASK_CONTAINER);
final ListTaskDisplayArea tdaList new ArrayList();
tdaList.add(defaultTaskDisplayArea);创建一个名为“DefaultTaskDisplayArea”的TaskDisplayArea,并将其添加到List中
2.创建HierarchyBuilder
final HierarchyBuilder rootHierarchy new HierarchyBuilder(root);HierarchyBuilder是什么是用来定义在整个逻辑显示的根里面所需的一些Feature HierarchyBuilder是在DisplayAreaPolicyBuilder中定义的 代码路径frameworks/base/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java /*** Builder to define {link Feature} and {link DisplayArea} hierarchy under a* {link RootDisplayArea}*/static 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 ArrayListDisplayAreaPolicyBuilder.Feature mFeatures new ArrayList();private final ArrayListTaskDisplayArea mTaskDisplayAreas new ArrayList();Nullableprivate DisplayArea.Tokens mImeContainer;HierarchyBuilder(RootDisplayArea root) {mRoot root;}......}从代码中我们可以看出HierarchyBuilder用来构建一个DisplayArea层级结构该层级结构的根节点 其构造方法HierarchyBuilder(RootDisplayArea root)传入的是RootDisplayArea的对象。 结合前面的configureSurfaces方法中我们可以发现传入的是DisplayContent即HierarchyBuilder以DisplayContent对象为根节点生成一个DisplayArea层级结构。
3.1添加ImeContainer到HierarchyBuilder
rootHierarchy.setImeContainer(imeContainer).setTaskDisplayAreas(tdaList);我们先看setImeContainer(imeContainer)部分。其中参数imeContainer是DisplayArea.Tokens的对象。
在DisplayContent中DisplayAreaPolicy初始化时传递了一个mImeWindowsContainer对应我们这里的imeContainer形参其是在DisplayContent中定义并初始化的 代码路径/frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java // Contains all IME window containers. Note that the z-ordering of the IME windows will depend// on the IME target. We mainly have this container grouping so we can keep track of all the IME// window containers together and move them in-sync if/when needed. We use a subclass of// WindowContainer which is omitted from screen magnification, as the IME is never magnified.// TODO(display-area): is no magnification in the comment still true?private final ImeContainer mImeWindowsContainer new ImeContainer(mWmService);ImeContainer就是输入法的容器其继承在DisplayContent中DisplayArea.Tokens /*** Container for IME windows.** This has some special behaviors:* - layers assignment is ignored except if setNeedsLayer() has been called before (and no* layer has been assigned since), to facilitate assigning the layer from the IME target, or* fall back if there is no target.* - the container doesnt always participate in window traversal, according to* {link #skipImeWindowsDuringTraversal()}*/private static class ImeContainer extends DisplayArea.Tokens {HierarchyBuilder的setImeContainer方法 代码路径frameworks/base/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java private DisplayArea.Tokens mImeContainer;/** Sets IME container as a child of this hierarchy root. */HierarchyBuilder setImeContainer(DisplayArea.Tokens imeContainer) {mImeContainer imeContainer;return this;}从代码中可以看出就是将DisplayContent的mImeWindowsContainer保存到了HierarchyBuilder的mImeContainer成员变量中后续创建DisplayArea层级结构时可以直接拿来使用。
3.2添加TaskDisplayArea到HierarchyBuilder
rootHierarchy.setImeContainer(imeContainer).setTaskDisplayAreas(tdaList);这里我们看setTaskDisplayAreas(tdaList)部分第一步【1.初始化TaskDisplayArea】的时候就已经把名为“DefaultTaskDisplayArea”的TaskDisplayArea,并将其添加到tdaList中 private final ArrayListTaskDisplayArea mTaskDisplayAreas new ArrayList();/*** Sets {link TaskDisplayArea} that are children of this hierarchy root.* {link DisplayArea} group must have at least one {link TaskDisplayArea}.*/HierarchyBuilder setTaskDisplayAreas(ListTaskDisplayArea taskDisplayAreas) {mTaskDisplayAreas.clear();mTaskDisplayAreas.addAll(taskDisplayAreas);return this;}虽然TaskDisplayArea是支持嵌套的并且这里也采用了一个ArrayList来管理TaskDisplayArea但是目前TaskDisplayArea只在这里被创建即目前一个DisplayContent只有一个名为“DefaultTaskDisplayArea”的TaskDisplayArea。从dumpsys activity containers 中我们也可以看到,整个文件也只有一个“DefaultTaskDisplayArea”
4.为HierarchyBuilder添加Feature
// Only trusted display can have system decorations.
configureTrustedHierarchyBuilder(rootHierarchy, wmService, content);configureTrustedHierarchyBuilder这个方法就在DisplayAreaPolicy.DefaultProvider内部
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());}}从代码中可以看到五大的FeatureWindowedMagnification、HideDisplayCutout、OneHanded、FullscreenMagnification、ImePlaceholder这些Feature其实也就是我们在dumpsys中看到那些还有一些关键方法all()、and()、except()、upto()、build()等 在我们正式开始聊这个几个Feature添加之前我们先来看看Feature是怎么定义的
Feature的定义
从HierarchyBuilder的addFeature方法跟踪发现Feature是在DisplayAreaPolicyBuilder中定义的 HierarchyBuilder addFeature(DisplayAreaPolicyBuilder.Feature feature) {mFeatures.add(feature);return this;}Feature的定义 代码路径/frameworks/base/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java /*** A feature that requires {link DisplayArea DisplayArea(s)}.*/static class Feature {private final String mName;private final int mId;private final boolean[] mWindowLayers;private final NewDisplayAreaSupplier mNewDisplayAreaSupplier;private Feature(String name, int id, boolean[] windowLayers,NewDisplayAreaSupplier newDisplayAreaSupplier) {mName name;mId id;mWindowLayers windowLayers;mNewDisplayAreaSupplier newDisplayAreaSupplier;}......}首先Feature代表的是DisplayArea的一个特征可以根据Feature来对不同的DisplayArea进行划分。
mName这个Feature的名字如上面的“WindowedMagnification”“HideDisplayCutout”之类的后续DisplayArea层级结构建立起来后每个DisplayArea的名字用的就是当前DisplayArea对应的那个Feature的名字。mIdFeature的ID如上面的FEATURE_WINDOWED_MAGNIFICATION和FEATURE_HIDE_DISPLAY_CUTOUT虽说是Feature的ID因为Feature又是DisplayArea的特征mWindowLayers代表了这个DisplayArea可以包含哪些层级对应的窗口mNewDisplayAreaSupplier只是一个接口内部定义一个create方法。
关键是其Feature内部定义Builder类以及其build()方法
Feature.Builder和Feature.Builder.build()
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;/*** Builds a new feature that applies to a set of window types as specified by the* builder methods.** pThe set of types is updated iteratively in the order of the method invocations.* For example, {code all().except(TYPE_STATUS_BAR)} expresses that a feature should* apply to all types except TYPE_STATUS_BAR.** pThe builder starts out with the feature not applying to any types.** param name the name of the feature.* param id of the feature. {see Feature#getId}*/Builder(WindowManagerPolicy policy, String name, int id) {mPolicy policy;mName name;mId id;mLayers new boolean[mPolicy.getMaxWindowLayer() 1];}......Feature build() {if (mExcludeRoundedCorner) {// Always put the rounded corner layer to the top most layer.mLayers[mPolicy.getMaxWindowLayer()] false;}return new Feature(mName, mId, mLayers.clone(), mNewDisplayAreaSupplier);}通过一套适用于具体的窗口类型构建方法来构建新Feature 其中mLayers new boolean[mPolicy.getMaxWindowLayer() 1]; mPolicy.getMaxWindowLayer()返回的是窗口最大层数。 /*** Returns the max window layer.* pNote that the max window layer should be higher that the maximum value which reported* by {link #getWindowLayerFromTypeLw(int, boolean)} to contain rounded corner overlay./p** see WindowManager.LayoutParams#PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY*/default int getMaxWindowLayer() {return 36;}代码中最大层数是36这里1则也就是mLayers new boolean[37]即窗口层级区间为[0,36] 在看看build()方法中的 mLayers[mPolicy.getMaxWindowLayer()] false;则表示mLayers[36] false即第36层在build时会置为false注mExcludeRoundedCorner这个变量的值一直是true没有改动
下面我们来说说构建Feature的关键星魂
构建Feature的核心方法
以下代码均在DisplayAreaPolicyBuilder.Feature.Builder中
Feature第一星魂all() /*** Set that the feature applies to all window types.*/Builder all() {Arrays.fill(mLayers, true);return this;}将mLayers数组中的所有元素都设置为true表示当前DisplayArea可以包含所有类型的窗口。 简述all()就是把所有类型窗口置为true添加
Feature第二星魂and() /*** Set that the feature applies to the given window types.*/Builder and(int... types) {for (int i 0; i types.length; i) {int type types[i];set(type, true);}return this;}先将传入的窗口类型先转换为对应的层级值然后将mLayers数组中与该层级值对应的元素设置为true表示该DisplayArea可以包含传入的窗口类型对应的窗口。 简述and就是把你传入的所有参数窗口类型置为true添加
Feature第三星魂except() /*** Set that the feature does not apply to the given window types.*/Builder except(int... types) {for (int i 0; i types.length; i) {int type types[i];set(type, false);}return this;}先将传入的窗口类型先转换为对应的层级值然后将mLayers数组中与该层级值对应的元素设置为false表示该DisplayArea不再包含传入的窗口类型对应的窗口。 简述except就是你传入的所有参数窗口类型置为false不添加
Feature第四星魂必点upTo() /*** 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;}先将传入的窗口类型先转换为对应的层级值然后将mLayers数组中与该层级值对应的的元素之前的所有元素包含该元素设置为true表示当前DisplayArea可以包含比传入的窗口类型层级值低的所有窗口。 简述upTo把就是[0,typeInclusive]区间内的所有类型窗口置为true添加。 其中layerFromType方法非常重要我们一起看看 private int layerFromType(int type, boolean internalWindows) {return mPolicy.getWindowLayerFromTypeLw(type, internalWindows);}调用的了WindowManagerPolicy.getWindowLayerFromTypeLw方法 /*** Returns the layer assignment for the window type. Allows you to control how different* kinds of windows are ordered on-screen.** param type The type of window being assigned.* param canAddInternalSystemWindow If the owner window associated with the type we are* evaluating can add internal system windows. I.e they have* {link Manifest.permission#INTERNAL_SYSTEM_WINDOW}. If true, alert window* types {link android.view.WindowManager.LayoutParams#isSystemAlertWindowType(int)}* can be assigned layers greater than the layer for* {link android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY} Else, their* layers would be lesser.* return int An arbitrary integer used to order windows, with lower numbers below higher ones.*/default int getWindowLayerFromTypeLw(int type, boolean canAddInternalSystemWindow) {return getWindowLayerFromTypeLw(type, canAddInternalSystemWindow,false /* roundedCornerOverlay */);}/*** Returns the layer assignment for the window type. Allows you to control how different* kinds of windows are ordered on-screen.** param type The type of window being assigned.* param canAddInternalSystemWindow If the owner window associated with the type we are* evaluating can add internal system windows. I.e they have* {link Manifest.permission#INTERNAL_SYSTEM_WINDOW}. If true, alert window* types {link android.view.WindowManager.LayoutParams#isSystemAlertWindowType(int)}* can be assigned layers greater than the layer for* {link android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY} Else, their* layers would be lesser.* param roundedCornerOverlay {#code true} to indicate that the owner window is rounded corner* overlay.* return int An arbitrary integer used to order windows, with lower numbers below higher ones.*/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 shouldnt 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;}}关于各窗口类型的解读可以参考链接: Android 窗口常见参数汇总
方法简述 这个方法返回给定窗口类型对应的层级值用于控制不同类型的窗口在屏幕上的显示层次。 type要分配的窗口的类型。 canAddInternalSystemWindow是否可以添加内部系统窗口。 例如假如我们有一个内部系统窗口且我们的这个参数canAddInternalSystemWindow为true的情况下则Alert Window窗口类型所分配的层级大于TYPE_APPLICATION_OVERLAY为false则小于TYPE_APPLICATION_OVERLAY可以对照代码验证看看 roundedCornerOverlay#code true表示所有者窗口是圆角覆盖。 返回值 int一个任意整数用于对窗口进行排序较低的数字在高数字的下面。
其中APPLICATION_LAYER的值为2即表示所有App窗口会被归类到这一个层级 而上述方法中的最后一句default中则表示所有没有分类的窗口层级为3 后面我们只需要查这个代码即可知道每个类型的返回值是多少
Feature的添加
WindowedMagnification 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());1.设置Feature的mName为WindowedMagnification。
2.设置Feature的mId为FEATURE_WINDOWED_MAGNIFICATION
3.upTo里面的参数是TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY32则代表[0,TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY]区间内全部添加
4.except里面参数是TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY32则除去该类型
最终我们可以得到WindowedMagnification的所包含的层级区间在[0,31]
HideDisplayCutout 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())1.设置Feature的mName为HideDisplayCutout。
2.设置Feature的mId为FEATURE_HIDE_DISPLAY_CUTOUT
3.all()把所有的窗口类型添加进来
4.except里面的类型踢掉TYPE_NAVIGATION_BAR(24)TYPE_NAVIGATION_BAR_PANEL(25)TYPE_STATUS_BAR(15)TYPE_NOTIFICATION_SHADE(17)
5.build()方法会把第36层从0开始算踢掉前面讲该方法时说过
最终我们可以得到HideDisplayCutout所包含的层级为0-16,18,20-23,26-35
OneHanded .addFeature(new Feature.Builder(wmService.mPolicy, OneHanded,FEATURE_ONE_HANDED).all().except(TYPE_NAVIGATION_BAR, TYPE_NAVIGATION_BAR_PANEL,TYPE_SECURE_SYSTEM_OVERLAY).build());1.设置Feature的mName为OneHanded。
2.设置Feature的mId为FEATURE_ONE_HANDED
3.all()把所有的窗口类型添加进来
4.except里面的类型踢掉TYPE_NAVIGATION_BAR(24)TYPE_NAVIGATION_BAR_PANEL(25)TYPE_SECURE_SYSTEM_OVERLAY(33)
5.去掉第36层
最终我们可以得到OneHanded所包含的层级为0-23,26-34,35
FullscreenMagnification 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())1.设置Feature的mName为FullscreenMagnification。
2.设置Feature的mId为FEATURE_FULLSCREEN_MAGNIFICATION
3.all()把所有的窗口类型添加进来
4.except里面的类型踢掉TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY(32)TYPE_INPUT_METHOD(13)TYPE_INPUT_METHOD_DIALOGERLAY(14)TYPE_MAGNIFICATION_OVERLAY(28)TYPE_NAVIGATION_BAR(24)TYPE_NAVIGATION_BAR_PANEL(25)
5.去掉第36层
最终我们可以得到FullscreenMagnification所包含的层级为0-12,15-23,26-27,29-31,33-35
ImePlaceholder .addFeature(new Feature.Builder(wmService.mPolicy, ImePlaceholder,FEATURE_IME_PLACEHOLDER).and(TYPE_INPUT_METHOD, TYPE_INPUT_METHOD_DIALOG).build());1.设置Feature的mName为ImePlaceholder。
2.设置Feature的mId为FEATURE_IME_PLACEHOLDER
3.and()把TYPE_INPUT_METHOD(13)TYPE_INPUT_METHOD_DIALOGERLAY(14)窗口类型添加进来
最终我们可以得到ImePlaceholder所包含的层级为13-14
Feature层级表
根据上面的添加过程我们整理为一张表
艺名真名影响窗口层级WindowedMagnificationFEATURE_WINDOWED_MAGNIFICATION0-31HideDisplayCutoutFEATURE_HIDE_DISPLAY_CUTOUT0-16,18,20-23,26-35OneHandedFEATURE_ONE_HANDED0-23,26-34,35FullscreenMagnificationFEATURE_FULLSCREEN_MAGNIFICATION0-12,15-23,26-27,29-31,33-35ImePlaceholderFEATURE_IME_PLACEHOLDER13-14
5.生成DisplayArea层级结构