Loading services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java +149 −24 Original line number Diff line number Diff line Loading @@ -23,20 +23,24 @@ import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR; import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY; import static android.view.WindowManagerPolicyConstants.APPLICATION_LAYER; import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER; import android.annotation.Nullable; import android.os.Bundle; import android.util.ArrayMap; import android.util.ArraySet; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.Preconditions; import com.android.server.policy.WindowManagerPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.function.BiFunction; /** * A builder for instantiating a complex {@link DisplayAreaPolicy} Loading Loading @@ -70,22 +74,93 @@ import java.util.Objects; */ class DisplayAreaPolicyBuilder { @Nullable private HierarchyBuilder mRootHierarchyBuilder; private ArrayList<HierarchyBuilder> mDisplayAreaGroupHierarchyBuilders = new ArrayList<>(); /** Defines the root hierarchy. */ /** * When a window is created, the policy will use this function to select the * {@link RootDisplayArea} to place that window in. The selected root can be either the one of * the {@link #mRootHierarchyBuilder} or the one of any of the * {@link #mDisplayAreaGroupHierarchyBuilders}. **/ @Nullable private BiFunction<WindowToken, Bundle, RootDisplayArea> mSelectRootForWindowFunc; /** Defines the root hierarchy for the whole logical display. */ DisplayAreaPolicyBuilder setRootHierarchy(HierarchyBuilder rootHierarchyBuilder) { // TODO(b/157683117): Add method to add sub root and root choosing func. mRootHierarchyBuilder = rootHierarchyBuilder; return this; } /** * Defines a DisplayAreaGroup hierarchy. Its root will be added as a child of the root * hierarchy. */ DisplayAreaPolicyBuilder addDisplayAreaGroupHierarchy( HierarchyBuilder displayAreaGroupHierarchy) { mDisplayAreaGroupHierarchyBuilders.add(displayAreaGroupHierarchy); return this; } /** The policy will use this function to find the root to place windows in. */ DisplayAreaPolicyBuilder setSelectRootForWindowFunc( BiFunction<WindowToken, Bundle, RootDisplayArea> selectRootForWindowFunc) { mSelectRootForWindowFunc = selectRootForWindowFunc; return this; } /** Makes sure the setting meets the requirement. */ private void validate() { if (mRootHierarchyBuilder == null) { throw new IllegalStateException("Root must be set for the display area policy."); } boolean containsImeContainer = mRootHierarchyBuilder.mImeContainer != null; boolean containsDefaultTda = containsDefaultTaskDisplayArea(mRootHierarchyBuilder); for (int i = 0; i < mDisplayAreaGroupHierarchyBuilders.size(); i++) { HierarchyBuilder hierarchyBuilder = mDisplayAreaGroupHierarchyBuilders.get(i); if (hierarchyBuilder.mTaskDisplayAreas.isEmpty()) { throw new IllegalStateException( "DisplayAreaGroup must contain at least one TaskDisplayArea."); } containsImeContainer = containsImeContainer || hierarchyBuilder.mImeContainer != null; containsDefaultTda = containsDefaultTda || containsDefaultTaskDisplayArea(hierarchyBuilder); } if (!containsImeContainer) { throw new IllegalStateException("IME container must be set."); } if (!containsDefaultTda) { throw new IllegalStateException("There must be a default TaskDisplayArea."); } } /** Checks if the given hierarchy contains the default {@link TaskDisplayArea}. */ private static boolean containsDefaultTaskDisplayArea(HierarchyBuilder displayAreaHierarchy) { for (int i = 0; i < displayAreaHierarchy.mTaskDisplayAreas.size(); i++) { if (displayAreaHierarchy.mTaskDisplayAreas.get(i).mFeatureId == FEATURE_DEFAULT_TASK_CONTAINER) { return true; } } return false; } Result build(WindowManagerService wmService) { Objects.requireNonNull(mRootHierarchyBuilder, "Root must be set for the display area policy."); Objects.requireNonNull(mRootHierarchyBuilder.mImeContainer, "Ime must not be null"); Preconditions.checkCollectionNotEmpty(mRootHierarchyBuilder.mTaskDisplayAreas, "TaskDisplayAreas must not be empty"); mRootHierarchyBuilder.build(); return new Result(wmService, mRootHierarchyBuilder.mRoot); validate(); // 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); } return new Result(wmService, mRootHierarchyBuilder.mRoot, displayAreaGroupRoots, mSelectRootForWindowFunc); } /** Loading Loading @@ -131,6 +206,14 @@ class DisplayAreaPolicyBuilder { /** Builds the {@link DisplayArea} hierarchy below root. */ private void build() { build(null /* displayAreaGroupHierarchyBuilders */); } /** * Builds the {@link DisplayArea} hierarchy below root. And adds the roots of those * {@link HierarchyBuilder} as children. */ private void build(@Nullable List<HierarchyBuilder> displayAreaGroupHierarchyBuilders) { final WindowManagerPolicy policy = mRoot.mWmService.mPolicy; final int maxWindowLayerCount = policy.getMaxWindowLayer(); final DisplayArea.Tokens[] displayAreaForLayer = Loading Loading @@ -215,7 +298,9 @@ class DisplayAreaPolicyBuilder { 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. addTaskDisplayAreasToLayer(areaForLayer[layer]); 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. Loading @@ -234,11 +319,11 @@ class DisplayAreaPolicyBuilder { // 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, mTaskDisplayAreas); mRoot.onHierarchyBuilt(mFeatures, displayAreaForLayer, featureAreas); } /** Adds all {@link TaskDisplayArea} to the specified layer */ private void addTaskDisplayAreasToLayer(PendingArea parentPendingArea) { /** Adds all {@link TaskDisplayArea} to the application layer. */ private void addTaskDisplayAreasToApplicationLayer(PendingArea parentPendingArea) { final int count = mTaskDisplayAreas.size(); for (int i = 0; i < count; i++) { PendingArea leafArea = Loading @@ -249,6 +334,24 @@ class DisplayAreaPolicyBuilder { } } /** Adds roots of the DisplayAreaGroups to the application layer. */ private void addDisplayAreaGroupsToApplicationLayer( DisplayAreaPolicyBuilder.PendingArea parentPendingArea, @Nullable List<HierarchyBuilder> displayAreaGroupHierarchyBuilders) { if (displayAreaGroupHierarchyBuilders == null) { return; } final int count = displayAreaGroupHierarchyBuilders.size(); for (int i = 0; i < count; i++) { DisplayAreaPolicyBuilder.PendingArea leafArea = new DisplayAreaPolicyBuilder.PendingArea( null /* feature */, APPLICATION_LAYER, parentPendingArea); leafArea.mExisting = displayAreaGroupHierarchyBuilders.get(i).mRoot; leafArea.mMaxLayer = APPLICATION_LAYER; parentPendingArea.mChildren.add(leafArea); } } private static int typeOfLayer(WindowManagerPolicy policy, int layer) { if (layer == APPLICATION_LAYER) { return LEAF_TYPE_TASK_CONTAINERS; Loading Loading @@ -401,9 +504,20 @@ class DisplayAreaPolicyBuilder { } static class Result extends DisplayAreaPolicy { final List<RootDisplayArea> mDisplayAreaGroupRoots; final BiFunction<WindowToken, Bundle, RootDisplayArea> mSelectRootForWindowFunc; Result(WindowManagerService wmService, RootDisplayArea root) { Result(WindowManagerService wmService, RootDisplayArea root, List<RootDisplayArea> displayAreaGroupRoots, @Nullable BiFunction<WindowToken, Bundle, RootDisplayArea> selectRootForWindowFunc) { super(wmService, root); mDisplayAreaGroupRoots = Collections.unmodifiableList(displayAreaGroupRoots); mSelectRootForWindowFunc = selectRootForWindowFunc == null // Always return the highest level root of the logical display when the func is // not specified. ? (window, options) -> mRoot : selectRootForWindowFunc; } @Override Loading @@ -414,27 +528,38 @@ class DisplayAreaPolicyBuilder { @VisibleForTesting DisplayArea.Tokens findAreaForToken(WindowToken token) { // TODO(b/157683117): Choose root/sub root from OEM provided func. return mRoot.findAreaForToken(token); return mSelectRootForWindowFunc.apply(token, token.mOptions).findAreaForToken(token); } @VisibleForTesting List<Feature> getFeatures() { // TODO(b/157683117): Also get feature from sub root. return new ArrayList<>(mRoot.mFeatures); Set<Feature> features = new ArraySet<>(); features.addAll(mRoot.mFeatures); for (int i = 0; i < mDisplayAreaGroupRoots.size(); i++) { features.addAll(mDisplayAreaGroupRoots.get(i).mFeatures); } return new ArrayList<>(features); } @Override public List<DisplayArea<? extends WindowContainer>> getDisplayAreas(int featureId) { // TODO(b/157683117): Also get display areas from sub root. List<Feature> features = getFeatures(); List<DisplayArea<? extends WindowContainer>> displayAreas = new ArrayList<>(); getDisplayAreas(mRoot, featureId, displayAreas); for (int i = 0; i < mDisplayAreaGroupRoots.size(); i++) { getDisplayAreas(mDisplayAreaGroupRoots.get(i), featureId, displayAreas); } return displayAreas; } private static void getDisplayAreas(RootDisplayArea root, int featureId, List<DisplayArea<? extends WindowContainer>> displayAreas) { List<Feature> features = root.mFeatures; for (int i = 0; i < features.size(); i++) { Feature feature = features.get(i); if (feature.mId == featureId) { return new ArrayList<>(mRoot.mFeatureToDisplayAreas.get(feature)); displayAreas.addAll(root.mFeatureToDisplayAreas.get(feature)); } } return new ArrayList<>(); } } Loading services/core/java/com/android/server/wm/DisplayContent.java +2 −1 Original line number Diff line number Diff line Loading @@ -71,6 +71,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN; import static android.view.WindowManager.TRANSIT_TASK_OPEN; import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT; import static android.window.DisplayAreaOrganizer.FEATURE_ROOT; import static android.window.DisplayAreaOrganizer.FEATURE_WINDOWED_MAGNIFICATION; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM; Loading Loading @@ -910,7 +911,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp * @param root {@link RootWindowContainer} */ DisplayContent(Display display, RootWindowContainer root) { super(root.mWindowManager); super(root.mWindowManager, "DisplayContent", FEATURE_ROOT); if (mWmService.mRoot.getDisplayContent(display.getDisplayId()) != null) { throw new IllegalArgumentException("Display with ID=" + display.getDisplayId() + " already exists=" Loading services/core/java/com/android/server/wm/RootDisplayArea.java +3 −14 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ package com.android.server.wm; import static android.view.WindowManagerPolicyConstants.APPLICATION_LAYER; import static android.window.DisplayAreaOrganizer.FEATURE_ROOT; import static com.android.server.wm.DisplayAreaPolicyBuilder.Feature; Loading @@ -44,19 +43,11 @@ class RootDisplayArea extends DisplayArea<DisplayArea> { /** Mapping from window layer to {@link DisplayArea.Tokens} that holds windows on that layer. */ private DisplayArea.Tokens[] mAreaForLayer; /** * List of {@link TaskDisplayArea} that are attached to this {@link DisplayArea} hierarchy. The * order is the same as their z-order. * * TODO(b/157683117): Instead of caching the TDAs, always traverse the hierarchy to get them. */ ArrayList<TaskDisplayArea> mTaskDisplayAreas; /** Whether the hierarchy has been built. */ private boolean mHasBuiltHierarchy; RootDisplayArea(WindowManagerService wms) { super(wms, Type.ANY, "RootDisplayArea", FEATURE_ROOT); RootDisplayArea(WindowManagerService wms, String name, int featureId) { super(wms, Type.ANY, name, featureId); } /** Finds the {@link DisplayArea.Tokens} that this type of window should be attached to. */ Loading @@ -73,15 +64,13 @@ class RootDisplayArea extends DisplayArea<DisplayArea> { /** Callback after {@link DisplayArea} hierarchy has been built. */ void onHierarchyBuilt(ArrayList<Feature> features, DisplayArea.Tokens[] areaForLayer, Map<Feature, List<DisplayArea<? extends WindowContainer>>> featureToDisplayAreas, ArrayList<TaskDisplayArea> taskDisplayAreas) { Map<Feature, List<DisplayArea<? extends WindowContainer>>> featureToDisplayAreas) { if (mHasBuiltHierarchy) { throw new IllegalStateException("Root should only build the hierarchy once"); } mHasBuiltHierarchy = true; mFeatures = Collections.unmodifiableList(features); mAreaForLayer = areaForLayer; mTaskDisplayAreas = taskDisplayAreas; mFeatureToDisplayAreas = featureToDisplayAreas; } } services/core/java/com/android/server/wm/WallpaperWindowToken.java +9 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.wm; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.os.Process.INVALID_UID; import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS; Loading @@ -24,6 +25,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIG import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import android.annotation.Nullable; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; Loading @@ -44,7 +46,13 @@ class WallpaperWindowToken extends WindowToken { WallpaperWindowToken(WindowManagerService service, IBinder token, boolean explicit, DisplayContent dc, boolean ownerCanManageAppTokens) { super(service, token, TYPE_WALLPAPER, explicit, dc, ownerCanManageAppTokens); this(service, token, explicit, dc, ownerCanManageAppTokens, null /* options */); } WallpaperWindowToken(WindowManagerService service, IBinder token, boolean explicit, DisplayContent dc, boolean ownerCanManageAppTokens, @Nullable Bundle options) { super(service, token, TYPE_WALLPAPER, explicit, dc, ownerCanManageAppTokens, INVALID_UID, false /* roundedCornerOverlay */, false /* fromClientToken */, options); dc.mWallpaperController.addWallpaperToken(this); setWindowingMode(WINDOWING_MODE_FULLSCREEN); } Loading services/core/java/com/android/server/wm/WindowManagerService.java +3 −2 Original line number Diff line number Diff line Loading @@ -2670,10 +2670,11 @@ public class WindowManagerService extends IWindowManager.Stub } // TODO(window-container): Clean up dead tokens if (type == TYPE_WALLPAPER) { new WallpaperWindowToken(this, binder, true, dc, callerCanManageAppTokens); new WallpaperWindowToken(this, binder, true, dc, callerCanManageAppTokens, options); } else { new WindowToken(this, binder, type, true, dc, callerCanManageAppTokens, callingUid, false /* roundedCornerOverlay */, fromClientToken); callingUid, false /* roundedCornerOverlay */, fromClientToken, options); } } } finally { Loading Loading
services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java +149 −24 Original line number Diff line number Diff line Loading @@ -23,20 +23,24 @@ import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR; import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY; import static android.view.WindowManagerPolicyConstants.APPLICATION_LAYER; import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER; import android.annotation.Nullable; import android.os.Bundle; import android.util.ArrayMap; import android.util.ArraySet; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.Preconditions; import com.android.server.policy.WindowManagerPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.function.BiFunction; /** * A builder for instantiating a complex {@link DisplayAreaPolicy} Loading Loading @@ -70,22 +74,93 @@ import java.util.Objects; */ class DisplayAreaPolicyBuilder { @Nullable private HierarchyBuilder mRootHierarchyBuilder; private ArrayList<HierarchyBuilder> mDisplayAreaGroupHierarchyBuilders = new ArrayList<>(); /** Defines the root hierarchy. */ /** * When a window is created, the policy will use this function to select the * {@link RootDisplayArea} to place that window in. The selected root can be either the one of * the {@link #mRootHierarchyBuilder} or the one of any of the * {@link #mDisplayAreaGroupHierarchyBuilders}. **/ @Nullable private BiFunction<WindowToken, Bundle, RootDisplayArea> mSelectRootForWindowFunc; /** Defines the root hierarchy for the whole logical display. */ DisplayAreaPolicyBuilder setRootHierarchy(HierarchyBuilder rootHierarchyBuilder) { // TODO(b/157683117): Add method to add sub root and root choosing func. mRootHierarchyBuilder = rootHierarchyBuilder; return this; } /** * Defines a DisplayAreaGroup hierarchy. Its root will be added as a child of the root * hierarchy. */ DisplayAreaPolicyBuilder addDisplayAreaGroupHierarchy( HierarchyBuilder displayAreaGroupHierarchy) { mDisplayAreaGroupHierarchyBuilders.add(displayAreaGroupHierarchy); return this; } /** The policy will use this function to find the root to place windows in. */ DisplayAreaPolicyBuilder setSelectRootForWindowFunc( BiFunction<WindowToken, Bundle, RootDisplayArea> selectRootForWindowFunc) { mSelectRootForWindowFunc = selectRootForWindowFunc; return this; } /** Makes sure the setting meets the requirement. */ private void validate() { if (mRootHierarchyBuilder == null) { throw new IllegalStateException("Root must be set for the display area policy."); } boolean containsImeContainer = mRootHierarchyBuilder.mImeContainer != null; boolean containsDefaultTda = containsDefaultTaskDisplayArea(mRootHierarchyBuilder); for (int i = 0; i < mDisplayAreaGroupHierarchyBuilders.size(); i++) { HierarchyBuilder hierarchyBuilder = mDisplayAreaGroupHierarchyBuilders.get(i); if (hierarchyBuilder.mTaskDisplayAreas.isEmpty()) { throw new IllegalStateException( "DisplayAreaGroup must contain at least one TaskDisplayArea."); } containsImeContainer = containsImeContainer || hierarchyBuilder.mImeContainer != null; containsDefaultTda = containsDefaultTda || containsDefaultTaskDisplayArea(hierarchyBuilder); } if (!containsImeContainer) { throw new IllegalStateException("IME container must be set."); } if (!containsDefaultTda) { throw new IllegalStateException("There must be a default TaskDisplayArea."); } } /** Checks if the given hierarchy contains the default {@link TaskDisplayArea}. */ private static boolean containsDefaultTaskDisplayArea(HierarchyBuilder displayAreaHierarchy) { for (int i = 0; i < displayAreaHierarchy.mTaskDisplayAreas.size(); i++) { if (displayAreaHierarchy.mTaskDisplayAreas.get(i).mFeatureId == FEATURE_DEFAULT_TASK_CONTAINER) { return true; } } return false; } Result build(WindowManagerService wmService) { Objects.requireNonNull(mRootHierarchyBuilder, "Root must be set for the display area policy."); Objects.requireNonNull(mRootHierarchyBuilder.mImeContainer, "Ime must not be null"); Preconditions.checkCollectionNotEmpty(mRootHierarchyBuilder.mTaskDisplayAreas, "TaskDisplayAreas must not be empty"); mRootHierarchyBuilder.build(); return new Result(wmService, mRootHierarchyBuilder.mRoot); validate(); // 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); } return new Result(wmService, mRootHierarchyBuilder.mRoot, displayAreaGroupRoots, mSelectRootForWindowFunc); } /** Loading Loading @@ -131,6 +206,14 @@ class DisplayAreaPolicyBuilder { /** Builds the {@link DisplayArea} hierarchy below root. */ private void build() { build(null /* displayAreaGroupHierarchyBuilders */); } /** * Builds the {@link DisplayArea} hierarchy below root. And adds the roots of those * {@link HierarchyBuilder} as children. */ private void build(@Nullable List<HierarchyBuilder> displayAreaGroupHierarchyBuilders) { final WindowManagerPolicy policy = mRoot.mWmService.mPolicy; final int maxWindowLayerCount = policy.getMaxWindowLayer(); final DisplayArea.Tokens[] displayAreaForLayer = Loading Loading @@ -215,7 +298,9 @@ class DisplayAreaPolicyBuilder { 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. addTaskDisplayAreasToLayer(areaForLayer[layer]); 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. Loading @@ -234,11 +319,11 @@ class DisplayAreaPolicyBuilder { // 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, mTaskDisplayAreas); mRoot.onHierarchyBuilt(mFeatures, displayAreaForLayer, featureAreas); } /** Adds all {@link TaskDisplayArea} to the specified layer */ private void addTaskDisplayAreasToLayer(PendingArea parentPendingArea) { /** Adds all {@link TaskDisplayArea} to the application layer. */ private void addTaskDisplayAreasToApplicationLayer(PendingArea parentPendingArea) { final int count = mTaskDisplayAreas.size(); for (int i = 0; i < count; i++) { PendingArea leafArea = Loading @@ -249,6 +334,24 @@ class DisplayAreaPolicyBuilder { } } /** Adds roots of the DisplayAreaGroups to the application layer. */ private void addDisplayAreaGroupsToApplicationLayer( DisplayAreaPolicyBuilder.PendingArea parentPendingArea, @Nullable List<HierarchyBuilder> displayAreaGroupHierarchyBuilders) { if (displayAreaGroupHierarchyBuilders == null) { return; } final int count = displayAreaGroupHierarchyBuilders.size(); for (int i = 0; i < count; i++) { DisplayAreaPolicyBuilder.PendingArea leafArea = new DisplayAreaPolicyBuilder.PendingArea( null /* feature */, APPLICATION_LAYER, parentPendingArea); leafArea.mExisting = displayAreaGroupHierarchyBuilders.get(i).mRoot; leafArea.mMaxLayer = APPLICATION_LAYER; parentPendingArea.mChildren.add(leafArea); } } private static int typeOfLayer(WindowManagerPolicy policy, int layer) { if (layer == APPLICATION_LAYER) { return LEAF_TYPE_TASK_CONTAINERS; Loading Loading @@ -401,9 +504,20 @@ class DisplayAreaPolicyBuilder { } static class Result extends DisplayAreaPolicy { final List<RootDisplayArea> mDisplayAreaGroupRoots; final BiFunction<WindowToken, Bundle, RootDisplayArea> mSelectRootForWindowFunc; Result(WindowManagerService wmService, RootDisplayArea root) { Result(WindowManagerService wmService, RootDisplayArea root, List<RootDisplayArea> displayAreaGroupRoots, @Nullable BiFunction<WindowToken, Bundle, RootDisplayArea> selectRootForWindowFunc) { super(wmService, root); mDisplayAreaGroupRoots = Collections.unmodifiableList(displayAreaGroupRoots); mSelectRootForWindowFunc = selectRootForWindowFunc == null // Always return the highest level root of the logical display when the func is // not specified. ? (window, options) -> mRoot : selectRootForWindowFunc; } @Override Loading @@ -414,27 +528,38 @@ class DisplayAreaPolicyBuilder { @VisibleForTesting DisplayArea.Tokens findAreaForToken(WindowToken token) { // TODO(b/157683117): Choose root/sub root from OEM provided func. return mRoot.findAreaForToken(token); return mSelectRootForWindowFunc.apply(token, token.mOptions).findAreaForToken(token); } @VisibleForTesting List<Feature> getFeatures() { // TODO(b/157683117): Also get feature from sub root. return new ArrayList<>(mRoot.mFeatures); Set<Feature> features = new ArraySet<>(); features.addAll(mRoot.mFeatures); for (int i = 0; i < mDisplayAreaGroupRoots.size(); i++) { features.addAll(mDisplayAreaGroupRoots.get(i).mFeatures); } return new ArrayList<>(features); } @Override public List<DisplayArea<? extends WindowContainer>> getDisplayAreas(int featureId) { // TODO(b/157683117): Also get display areas from sub root. List<Feature> features = getFeatures(); List<DisplayArea<? extends WindowContainer>> displayAreas = new ArrayList<>(); getDisplayAreas(mRoot, featureId, displayAreas); for (int i = 0; i < mDisplayAreaGroupRoots.size(); i++) { getDisplayAreas(mDisplayAreaGroupRoots.get(i), featureId, displayAreas); } return displayAreas; } private static void getDisplayAreas(RootDisplayArea root, int featureId, List<DisplayArea<? extends WindowContainer>> displayAreas) { List<Feature> features = root.mFeatures; for (int i = 0; i < features.size(); i++) { Feature feature = features.get(i); if (feature.mId == featureId) { return new ArrayList<>(mRoot.mFeatureToDisplayAreas.get(feature)); displayAreas.addAll(root.mFeatureToDisplayAreas.get(feature)); } } return new ArrayList<>(); } } Loading
services/core/java/com/android/server/wm/DisplayContent.java +2 −1 Original line number Diff line number Diff line Loading @@ -71,6 +71,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN; import static android.view.WindowManager.TRANSIT_TASK_OPEN; import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT; import static android.window.DisplayAreaOrganizer.FEATURE_ROOT; import static android.window.DisplayAreaOrganizer.FEATURE_WINDOWED_MAGNIFICATION; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM; Loading Loading @@ -910,7 +911,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp * @param root {@link RootWindowContainer} */ DisplayContent(Display display, RootWindowContainer root) { super(root.mWindowManager); super(root.mWindowManager, "DisplayContent", FEATURE_ROOT); if (mWmService.mRoot.getDisplayContent(display.getDisplayId()) != null) { throw new IllegalArgumentException("Display with ID=" + display.getDisplayId() + " already exists=" Loading
services/core/java/com/android/server/wm/RootDisplayArea.java +3 −14 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ package com.android.server.wm; import static android.view.WindowManagerPolicyConstants.APPLICATION_LAYER; import static android.window.DisplayAreaOrganizer.FEATURE_ROOT; import static com.android.server.wm.DisplayAreaPolicyBuilder.Feature; Loading @@ -44,19 +43,11 @@ class RootDisplayArea extends DisplayArea<DisplayArea> { /** Mapping from window layer to {@link DisplayArea.Tokens} that holds windows on that layer. */ private DisplayArea.Tokens[] mAreaForLayer; /** * List of {@link TaskDisplayArea} that are attached to this {@link DisplayArea} hierarchy. The * order is the same as their z-order. * * TODO(b/157683117): Instead of caching the TDAs, always traverse the hierarchy to get them. */ ArrayList<TaskDisplayArea> mTaskDisplayAreas; /** Whether the hierarchy has been built. */ private boolean mHasBuiltHierarchy; RootDisplayArea(WindowManagerService wms) { super(wms, Type.ANY, "RootDisplayArea", FEATURE_ROOT); RootDisplayArea(WindowManagerService wms, String name, int featureId) { super(wms, Type.ANY, name, featureId); } /** Finds the {@link DisplayArea.Tokens} that this type of window should be attached to. */ Loading @@ -73,15 +64,13 @@ class RootDisplayArea extends DisplayArea<DisplayArea> { /** Callback after {@link DisplayArea} hierarchy has been built. */ void onHierarchyBuilt(ArrayList<Feature> features, DisplayArea.Tokens[] areaForLayer, Map<Feature, List<DisplayArea<? extends WindowContainer>>> featureToDisplayAreas, ArrayList<TaskDisplayArea> taskDisplayAreas) { Map<Feature, List<DisplayArea<? extends WindowContainer>>> featureToDisplayAreas) { if (mHasBuiltHierarchy) { throw new IllegalStateException("Root should only build the hierarchy once"); } mHasBuiltHierarchy = true; mFeatures = Collections.unmodifiableList(features); mAreaForLayer = areaForLayer; mTaskDisplayAreas = taskDisplayAreas; mFeatureToDisplayAreas = featureToDisplayAreas; } }
services/core/java/com/android/server/wm/WallpaperWindowToken.java +9 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.wm; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.os.Process.INVALID_UID; import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS; Loading @@ -24,6 +25,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIG import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import android.annotation.Nullable; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; Loading @@ -44,7 +46,13 @@ class WallpaperWindowToken extends WindowToken { WallpaperWindowToken(WindowManagerService service, IBinder token, boolean explicit, DisplayContent dc, boolean ownerCanManageAppTokens) { super(service, token, TYPE_WALLPAPER, explicit, dc, ownerCanManageAppTokens); this(service, token, explicit, dc, ownerCanManageAppTokens, null /* options */); } WallpaperWindowToken(WindowManagerService service, IBinder token, boolean explicit, DisplayContent dc, boolean ownerCanManageAppTokens, @Nullable Bundle options) { super(service, token, TYPE_WALLPAPER, explicit, dc, ownerCanManageAppTokens, INVALID_UID, false /* roundedCornerOverlay */, false /* fromClientToken */, options); dc.mWallpaperController.addWallpaperToken(this); setWindowingMode(WINDOWING_MODE_FULLSCREEN); } Loading
services/core/java/com/android/server/wm/WindowManagerService.java +3 −2 Original line number Diff line number Diff line Loading @@ -2670,10 +2670,11 @@ public class WindowManagerService extends IWindowManager.Stub } // TODO(window-container): Clean up dead tokens if (type == TYPE_WALLPAPER) { new WallpaperWindowToken(this, binder, true, dc, callerCanManageAppTokens); new WallpaperWindowToken(this, binder, true, dc, callerCanManageAppTokens, options); } else { new WindowToken(this, binder, type, true, dc, callerCanManageAppTokens, callingUid, false /* roundedCornerOverlay */, fromClientToken); callingUid, false /* roundedCornerOverlay */, fromClientToken, options); } } } finally { Loading