Loading core/java/android/window/DisplayAreaOrganizer.java +7 −0 Original line number Diff line number Diff line Loading @@ -83,6 +83,13 @@ public class DisplayAreaOrganizer extends WindowOrganizer { */ public static final int FEATURE_HIDE_DISPLAY_CUTOUT = FEATURE_SYSTEM_FIRST + 6; /** * Display area that the IME container can be placed in. Should be enabled on every root * hierarchy if IME container may be reparented to that hierarchy when the IME target changed. * @hide */ public static final int FEATURE_IME_PLACEHOLDER = FEATURE_SYSTEM_FIRST + 7; /** * The last boundary of display area for system features */ Loading services/core/java/com/android/server/wm/DisplayAreaPolicy.java +7 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER; import static android.window.DisplayAreaOrganizer.FEATURE_FULLSCREEN_MAGNIFICATION; import static android.window.DisplayAreaOrganizer.FEATURE_HIDE_DISPLAY_CUTOUT; import static android.window.DisplayAreaOrganizer.FEATURE_IME_PLACEHOLDER; import static android.window.DisplayAreaOrganizer.FEATURE_ONE_HANDED; import static android.window.DisplayAreaOrganizer.FEATURE_WINDOWED_MAGNIFICATION; Loading Loading @@ -94,6 +95,8 @@ public abstract class DisplayAreaPolicy { // 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. HierarchyBuilder rootHierarchy = new HierarchyBuilder(root) // WindowedMagnification should be on the top so that there is only one surface // to be magnified. .addFeature(new Feature.Builder(wmService.mPolicy, "WindowedMagnification", FEATURE_WINDOWED_MAGNIFICATION) .upTo(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY) Loading @@ -120,6 +123,10 @@ public abstract class DisplayAreaPolicy { 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()) .setImeContainer(imeContainer) .setTaskDisplayAreas(tdaList); Loading services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java +2 −2 Original line number Diff line number Diff line Loading @@ -283,7 +283,7 @@ class DisplayAreaPolicyBuilder { final int maxWindowLayerCount = policy.getMaxWindowLayer(); final DisplayArea.Tokens[] displayAreaForLayer = new DisplayArea.Tokens[maxWindowLayerCount]; final Map<Feature, List<DisplayArea<? extends WindowContainer>>> featureAreas = final Map<Feature, List<DisplayArea<WindowContainer>>> featureAreas = new ArrayMap<>(mFeatures.size()); for (int i = 0; i < mFeatures.size(); i++) { featureAreas.put(mFeatures.get(i), new ArrayList<>()); Loading Loading @@ -678,7 +678,7 @@ class DisplayAreaPolicyBuilder { } void instantiateChildren(DisplayArea<DisplayArea> parent, DisplayArea.Tokens[] areaForLayer, int level, Map<Feature, List<DisplayArea<? extends WindowContainer>>> areas) { int level, Map<Feature, List<DisplayArea<WindowContainer>>> areas) { mChildren.sort(Comparator.comparingInt(pendingArea -> pendingArea.mMinLayer)); for (int i = 0; i < mChildren.size(); i++) { final PendingArea child = mChildren.get(i); Loading services/core/java/com/android/server/wm/DisplayContent.java +17 −2 Original line number Diff line number Diff line Loading @@ -3573,7 +3573,14 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp return mWmService.mForceDesktopModeOnExternalDisplays && !isDefaultDisplay && !isPrivate(); } private void setInputMethodTarget(WindowState target, boolean targetWaitingAnim) { /** * Sets the window the IME is on top of. * @param target window to place the IME surface on top of. If {@code null}, the IME will be * placed at its parent's surface. * @param targetWaitingAnim if {@code true}, hold off on modifying the animation layer of * the target. */ private void setInputMethodTarget(@Nullable WindowState target, boolean targetWaitingAnim) { if (target == mInputMethodTarget && mInputMethodTargetWaitingAnim == targetWaitingAnim) { return; } Loading @@ -3581,6 +3588,14 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp mInputMethodTarget = target; mInputMethodTargetWaitingAnim = targetWaitingAnim; assignWindowLayers(true /* setLayoutNeeded */); if (target != null) { RootDisplayArea targetRoot = target.getRootDisplayArea(); if (targetRoot != null) { // Reposition the IME container to the target root to get the correct bounds and // config. targetRoot.placeImeContainer(mImeWindowsContainers); } } updateImeParent(); updateImeControlTarget(); } Loading Loading @@ -4699,7 +4714,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } @VisibleForTesting WindowContainer<?> getImeContainer() { DisplayArea.Tokens getImeContainer() { return mImeWindowsContainers; } Loading services/core/java/com/android/server/wm/RootDisplayArea.java +32 −2 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.wm; import static android.view.WindowManagerPolicyConstants.APPLICATION_LAYER; import static android.window.DisplayAreaOrganizer.FEATURE_IME_PLACEHOLDER; import static com.android.server.wm.DisplayAreaPolicyBuilder.Feature; Loading @@ -39,7 +40,7 @@ class RootDisplayArea extends DisplayArea<DisplayArea> { * Mapping from policy supported {@link Feature} to list of {@link DisplayArea} created to cover * all the window types that the {@link Feature} will be applied to. */ Map<Feature, List<DisplayArea<? extends WindowContainer>>> mFeatureToDisplayAreas; Map<Feature, List<DisplayArea<WindowContainer>>> mFeatureToDisplayAreas; /** Mapping from window layer to {@link DisplayArea.Tokens} that holds windows on that layer. */ private DisplayArea.Tokens[] mAreaForLayer; Loading @@ -61,6 +62,35 @@ class RootDisplayArea extends DisplayArea<DisplayArea> { return false; } /** * Places the IME container below this root, so that it's bounds and config will be updated to * match the root. */ void placeImeContainer(DisplayArea.Tokens imeContainer) { if (imeContainer.getRootDisplayArea() == this) { // No need to reparent if IME container is below the same root. return; } List<Feature> features = mFeatures; for (int i = 0; i < features.size(); i++) { Feature feature = features.get(i); if (feature.getId() == FEATURE_IME_PLACEHOLDER) { List<DisplayArea<WindowContainer>> imeDisplayAreas = mFeatureToDisplayAreas.get(feature); if (imeDisplayAreas.size() != 1) { throw new IllegalStateException("There must be exactly one DisplayArea for the " + "FEATURE_IME_PLACEHOLDER"); } imeContainer.reparent(imeDisplayAreas.get(0), POSITION_TOP); return; } } throw new IllegalStateException( "There is no FEATURE_IME_PLACEHOLDER in this root to place the IME container"); } /** Finds the {@link DisplayArea.Tokens} that this type of window should be attached to. */ DisplayArea.Tokens findAreaForToken(WindowToken token) { int windowLayerFromType = token.getWindowLayerFromType(); Loading @@ -75,7 +105,7 @@ 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) { Map<Feature, List<DisplayArea<WindowContainer>>> featureToDisplayAreas) { if (mHasBuiltHierarchy) { throw new IllegalStateException("Root should only build the hierarchy once"); } Loading Loading
core/java/android/window/DisplayAreaOrganizer.java +7 −0 Original line number Diff line number Diff line Loading @@ -83,6 +83,13 @@ public class DisplayAreaOrganizer extends WindowOrganizer { */ public static final int FEATURE_HIDE_DISPLAY_CUTOUT = FEATURE_SYSTEM_FIRST + 6; /** * Display area that the IME container can be placed in. Should be enabled on every root * hierarchy if IME container may be reparented to that hierarchy when the IME target changed. * @hide */ public static final int FEATURE_IME_PLACEHOLDER = FEATURE_SYSTEM_FIRST + 7; /** * The last boundary of display area for system features */ Loading
services/core/java/com/android/server/wm/DisplayAreaPolicy.java +7 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER; import static android.window.DisplayAreaOrganizer.FEATURE_FULLSCREEN_MAGNIFICATION; import static android.window.DisplayAreaOrganizer.FEATURE_HIDE_DISPLAY_CUTOUT; import static android.window.DisplayAreaOrganizer.FEATURE_IME_PLACEHOLDER; import static android.window.DisplayAreaOrganizer.FEATURE_ONE_HANDED; import static android.window.DisplayAreaOrganizer.FEATURE_WINDOWED_MAGNIFICATION; Loading Loading @@ -94,6 +95,8 @@ public abstract class DisplayAreaPolicy { // 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. HierarchyBuilder rootHierarchy = new HierarchyBuilder(root) // WindowedMagnification should be on the top so that there is only one surface // to be magnified. .addFeature(new Feature.Builder(wmService.mPolicy, "WindowedMagnification", FEATURE_WINDOWED_MAGNIFICATION) .upTo(TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY) Loading @@ -120,6 +123,10 @@ public abstract class DisplayAreaPolicy { 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()) .setImeContainer(imeContainer) .setTaskDisplayAreas(tdaList); Loading
services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java +2 −2 Original line number Diff line number Diff line Loading @@ -283,7 +283,7 @@ class DisplayAreaPolicyBuilder { final int maxWindowLayerCount = policy.getMaxWindowLayer(); final DisplayArea.Tokens[] displayAreaForLayer = new DisplayArea.Tokens[maxWindowLayerCount]; final Map<Feature, List<DisplayArea<? extends WindowContainer>>> featureAreas = final Map<Feature, List<DisplayArea<WindowContainer>>> featureAreas = new ArrayMap<>(mFeatures.size()); for (int i = 0; i < mFeatures.size(); i++) { featureAreas.put(mFeatures.get(i), new ArrayList<>()); Loading Loading @@ -678,7 +678,7 @@ class DisplayAreaPolicyBuilder { } void instantiateChildren(DisplayArea<DisplayArea> parent, DisplayArea.Tokens[] areaForLayer, int level, Map<Feature, List<DisplayArea<? extends WindowContainer>>> areas) { int level, Map<Feature, List<DisplayArea<WindowContainer>>> areas) { mChildren.sort(Comparator.comparingInt(pendingArea -> pendingArea.mMinLayer)); for (int i = 0; i < mChildren.size(); i++) { final PendingArea child = mChildren.get(i); Loading
services/core/java/com/android/server/wm/DisplayContent.java +17 −2 Original line number Diff line number Diff line Loading @@ -3573,7 +3573,14 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp return mWmService.mForceDesktopModeOnExternalDisplays && !isDefaultDisplay && !isPrivate(); } private void setInputMethodTarget(WindowState target, boolean targetWaitingAnim) { /** * Sets the window the IME is on top of. * @param target window to place the IME surface on top of. If {@code null}, the IME will be * placed at its parent's surface. * @param targetWaitingAnim if {@code true}, hold off on modifying the animation layer of * the target. */ private void setInputMethodTarget(@Nullable WindowState target, boolean targetWaitingAnim) { if (target == mInputMethodTarget && mInputMethodTargetWaitingAnim == targetWaitingAnim) { return; } Loading @@ -3581,6 +3588,14 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp mInputMethodTarget = target; mInputMethodTargetWaitingAnim = targetWaitingAnim; assignWindowLayers(true /* setLayoutNeeded */); if (target != null) { RootDisplayArea targetRoot = target.getRootDisplayArea(); if (targetRoot != null) { // Reposition the IME container to the target root to get the correct bounds and // config. targetRoot.placeImeContainer(mImeWindowsContainers); } } updateImeParent(); updateImeControlTarget(); } Loading Loading @@ -4699,7 +4714,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp } @VisibleForTesting WindowContainer<?> getImeContainer() { DisplayArea.Tokens getImeContainer() { return mImeWindowsContainers; } Loading
services/core/java/com/android/server/wm/RootDisplayArea.java +32 −2 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.wm; import static android.view.WindowManagerPolicyConstants.APPLICATION_LAYER; import static android.window.DisplayAreaOrganizer.FEATURE_IME_PLACEHOLDER; import static com.android.server.wm.DisplayAreaPolicyBuilder.Feature; Loading @@ -39,7 +40,7 @@ class RootDisplayArea extends DisplayArea<DisplayArea> { * Mapping from policy supported {@link Feature} to list of {@link DisplayArea} created to cover * all the window types that the {@link Feature} will be applied to. */ Map<Feature, List<DisplayArea<? extends WindowContainer>>> mFeatureToDisplayAreas; Map<Feature, List<DisplayArea<WindowContainer>>> mFeatureToDisplayAreas; /** Mapping from window layer to {@link DisplayArea.Tokens} that holds windows on that layer. */ private DisplayArea.Tokens[] mAreaForLayer; Loading @@ -61,6 +62,35 @@ class RootDisplayArea extends DisplayArea<DisplayArea> { return false; } /** * Places the IME container below this root, so that it's bounds and config will be updated to * match the root. */ void placeImeContainer(DisplayArea.Tokens imeContainer) { if (imeContainer.getRootDisplayArea() == this) { // No need to reparent if IME container is below the same root. return; } List<Feature> features = mFeatures; for (int i = 0; i < features.size(); i++) { Feature feature = features.get(i); if (feature.getId() == FEATURE_IME_PLACEHOLDER) { List<DisplayArea<WindowContainer>> imeDisplayAreas = mFeatureToDisplayAreas.get(feature); if (imeDisplayAreas.size() != 1) { throw new IllegalStateException("There must be exactly one DisplayArea for the " + "FEATURE_IME_PLACEHOLDER"); } imeContainer.reparent(imeDisplayAreas.get(0), POSITION_TOP); return; } } throw new IllegalStateException( "There is no FEATURE_IME_PLACEHOLDER in this root to place the IME container"); } /** Finds the {@link DisplayArea.Tokens} that this type of window should be attached to. */ DisplayArea.Tokens findAreaForToken(WindowToken token) { int windowLayerFromType = token.getWindowLayerFromType(); Loading @@ -75,7 +105,7 @@ 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) { Map<Feature, List<DisplayArea<WindowContainer>>> featureToDisplayAreas) { if (mHasBuiltHierarchy) { throw new IllegalStateException("Root should only build the hierarchy once"); } Loading