Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6ba5a463 authored by Chris Li's avatar Chris Li
Browse files

Reparent IME container to the root of the IME target window

Reparent IME container so that it's bounds and config will be updated to
match the RootDisplayArea.

Bug: 156355859
Test: manual: test with dual display policy
Change-Id: Ia9c4f6c73c2a6b8ecbf2cd9f6feb39967ebff80c
parent 4a14b48d
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -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
     */
+7 −0
Original line number Diff line number Diff line
@@ -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;

@@ -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)
@@ -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);

+2 −2
Original line number Diff line number Diff line
@@ -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<>());
@@ -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);
+17 −2
Original line number Diff line number Diff line
@@ -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;
        }
@@ -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();
    }
@@ -4699,7 +4714,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
    }

    @VisibleForTesting
    WindowContainer<?> getImeContainer() {
    DisplayArea.Tokens getImeContainer() {
        return mImeWindowsContainers;
    }

+32 −2
Original line number Diff line number Diff line
@@ -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;

@@ -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;
@@ -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();
@@ -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