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

Commit 99400198 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fix showing the IME from EmbeddedWindow" into main

parents fa55e4a9 9f9e91c2
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -587,7 +587,14 @@ public class WindowlessWindowManager implements IWindowSession {

    @Override
    public void updateRequestedVisibleTypes(IWindow window,
            @InsetsType int requestedVisibleTypes, @Nullable ImeTracker.Token imeStatsToken)  {
            @InsetsType int requestedVisibleTypes, @Nullable ImeTracker.Token imeStatsToken)
            throws RemoteException {
        if (android.view.inputmethod.Flags.refactorInsetsController()) {
            // Embedded windows do not control insets (except for IME). The host window is
            // responsible for controlling the insets.
            mRealWm.updateRequestedVisibleTypes(window,
                    requestedVisibleTypes & WindowInsets.Type.ime(), imeStatsToken);
        }
    }

    @Override
+16 −8
Original line number Diff line number Diff line
@@ -303,21 +303,29 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged
                            lastSurfacePosition);
                } else {
                    if (!haveSameLeash(mImeSourceControl, imeSourceControl)) {
                        applyVisibilityToLeash(imeSourceControl);

                        if (android.view.inputmethod.Flags.refactorInsetsController()) {
                            pendingImeStartAnimation = true;
                            // The starting point for the IME should be it's previous state
                            // (whether it is initiallyVisible or not)
                            updateImeVisibility(imeSourceControl.isInitiallyVisible());
                        }
                        applyVisibilityToLeash(imeSourceControl);
                    }
                    if (!mImeShowing) {
                        removeImeSurface(mDisplayId);
                    }
                }
            } else if (!android.view.inputmethod.Flags.refactorInsetsController()
            } else {
                if (!android.view.inputmethod.Flags.refactorInsetsController()
                        && mAnimation != null) {
                // we don"t want to cancel the hide animation, when the control is lost, but
                    // we don't want to cancel the hide animation, when the control is lost, but
                    // continue the bar to slide to the end (even without visible IME)
                    mAnimation.cancel();
                } else if (android.view.inputmethod.Flags.refactorInsetsController() && mImeShowing
                        && mAnimation == null) {
                    // There is no leash, so the IME cannot be in a showing state
                    updateImeVisibility(false);
                }
            }

            // Make mImeSourceControl point to the new control before starting the animation.
@@ -341,7 +349,7 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged

            if (android.view.inputmethod.Flags.refactorInsetsController()) {
                if (pendingImeStartAnimation) {
                    startAnimation(true, true /* forceRestart */);
                    startAnimation(mImeRequestedVisible, true /* forceRestart */);
                }
            }
        }
+15 −6
Original line number Diff line number Diff line
@@ -707,6 +707,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
    @Retention(RetentionPolicy.SOURCE)
    @interface InputMethodTarget {}

    /** The surface parent window of the IME container. */
    private WindowContainer mInputMethodSurfaceParentWindow;
    /** The surface parent of the IME container. */
    @VisibleForTesting
    SurfaceControl mInputMethodSurfaceParent;
@@ -1529,6 +1531,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        return mDisplayRotation.getLastOrientation();
    }

    WindowContainer getImeParentWindow() {
        return mInputMethodSurfaceParentWindow;
    }

    void registerRemoteAnimations(RemoteAnimationDefinition definition) {
        mAppTransitionController.registerRemoteAnimations(definition);
    }
@@ -4733,13 +4739,17 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
                Slog.i(TAG_WM, "ImeContainer is organized. Skip updateImeParent.");
            }
            // Leave the ImeContainer where the DisplayAreaPolicy placed it.
            // FEATURE_IME is organized by vendor so they are responible for placing the surface.
            // FEATURE_IME is organized by vendor so they are responsible for placing the surface.
            mInputMethodSurfaceParentWindow = null;
            mInputMethodSurfaceParent = null;
            return;
        }

        final SurfaceControl newParent = computeImeParent();
        final var newParentWindow = computeImeParent();
        final SurfaceControl newParent =
                newParentWindow != null ? newParentWindow.getSurfaceControl() : null;
        if (newParent != null && newParent != mInputMethodSurfaceParent) {
            mInputMethodSurfaceParentWindow = newParentWindow;
            mInputMethodSurfaceParent = newParent;
            getSyncTransaction().reparent(mImeWindowsContainer.mSurfaceControl, newParent);
            if (DEBUG_IME_VISIBILITY) {
@@ -4800,7 +4810,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
     * Computes the window the IME should be attached to.
     */
    @VisibleForTesting
    SurfaceControl computeImeParent() {
    WindowContainer computeImeParent() {
        if (!ImeTargetVisibilityPolicy.canComputeImeParent(mImeLayeringTarget, mImeInputTarget)) {
            return null;
        }
@@ -4808,11 +4818,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        // screen. If it's not covering the entire screen the IME might extend beyond the apps
        // bounds.
        if (shouldImeAttachedToApp()) {
            return mImeLayeringTarget.mActivityRecord.getSurfaceControl();
            return mImeLayeringTarget.mActivityRecord;
        }
        // Otherwise, we just attach it to where the display area policy put it.
        return mImeWindowsContainer.getParent() != null
                ? mImeWindowsContainer.getParent().getSurfaceControl() : null;
        return mImeWindowsContainer.getParent();
    }

    void setLayoutNeeded() {
+31 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import android.view.InputApplicationHandle;
import android.view.InputChannel;
import android.view.WindowInsets;
import android.window.InputTransferToken;

import com.android.internal.protolog.ProtoLog;
@@ -222,6 +223,10 @@ class EmbeddedWindowController {

        private boolean mIsFocusable;

        // The EmbeddedWindow can only request the IME. All other insets types are requested by
        // the host window.
        private @WindowInsets.Type.InsetsType int mRequestedVisibleTypes = 0;

        /**
         * @param session  calling session to check ownership of the window
         * @param clientToken client token used to clean up the map if the embedding process dies
@@ -310,6 +315,27 @@ class EmbeddedWindowController {
            return mClient;
        }

        @Override
        public boolean isRequestedVisible(@WindowInsets.Type.InsetsType int types) {
            return (mRequestedVisibleTypes & types) != 0;
        }

        @Override
        public @WindowInsets.Type.InsetsType int getRequestedVisibleTypes() {
            return mRequestedVisibleTypes;
        }

        /**
         * Only the IME can be requested from the EmbeddedWindow.
         * @param requestedVisibleTypes other types than {@link WindowInsets.Type.IME} are
         *                              not sent to system server via WindowlessWindowManager.
         */
        void setRequestedVisibleTypes(@WindowInsets.Type.InsetsType int requestedVisibleTypes) {
            if (mRequestedVisibleTypes != requestedVisibleTypes) {
                mRequestedVisibleTypes = requestedVisibleTypes;
            }
        }

        @Override
        public int getPid() {
            return mOwnerPid;
@@ -375,6 +401,11 @@ class EmbeddedWindowController {

        @Override
        public boolean shouldControlIme() {
            if (android.view.inputmethod.Flags.refactorInsetsController()) {
                // EmbeddedWindow should never be able to control the IME directly, but only the
                // RemoteInsetsControlTarget.
                return false;
            }
            return mHostWindowState != null;
        }

+16 −21
Original line number Diff line number Diff line
@@ -268,7 +268,7 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider {

    // TODO(b/353463205) change statsToken to be NonNull, after the flag is permanently enabled
    @Override
    protected boolean updateClientVisibility(InsetsControlTarget caller,
    protected boolean updateClientVisibility(InsetsTarget caller,
            @Nullable ImeTracker.Token statsToken) {
        InsetsControlTarget controlTarget = getControlTarget();
        if (caller != controlTarget) {
@@ -283,12 +283,13 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider {
                        ImeTracker.forLogging().onProgress(statsToken,
                                ImeTracker.PHASE_WM_SET_REMOTE_TARGET_IME_VISIBILITY);
                        controlTarget.setImeInputTargetRequestedVisibility(imeVisible);
                    } else {
                    } else if (caller instanceof InsetsControlTarget) {
                        // In case of a virtual display that cannot show the IME, the
                        // controlTarget will be null here, as no controlTarget was set yet. In
                        // that case, proceed similar to the multi window mode (fallback =
                        // RemoteInsetsControlTarget of the default display)
                        controlTarget = mDisplayContent.getImeHostOrFallback(caller.getWindow());
                        controlTarget = mDisplayContent.getImeHostOrFallback(
                                ((InsetsControlTarget) caller).getWindow());

                        if (controlTarget != caller) {
                            ImeTracker.forLogging().onProgress(statsToken,
@@ -300,8 +301,7 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider {
                        }
                    }

                    WindowState windowState = caller.getWindow();
                    invokeOnImeRequestedChangedListener(windowState, statsToken);
                    invokeOnImeRequestedChangedListener(caller, statsToken);
                } else {
                    // TODO(b/353463205) add ImeTracker?
                }
@@ -309,20 +309,16 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider {
            return false;
        }
        boolean changed = super.updateClientVisibility(caller, statsToken);
        if (!Flags.refactorInsetsController()) {
        if (!Flags.refactorInsetsController() && caller instanceof InsetsControlTarget) {
            if (changed && caller.isRequestedVisible(mSource.getType())) {
                reportImeDrawnForOrganizerIfNeeded(caller);
                reportImeDrawnForOrganizerIfNeeded((InsetsControlTarget) caller);
            }
        }
        changed |= mDisplayContent.onImeInsetsClientVisibilityUpdate();
        if (Flags.refactorInsetsController()) {
            if (changed) {
                // RemoteInsetsControlTarget does not have a window. In this case, we use the
                // windowState from the imeInputTarget
                WindowState windowState = caller.getWindow() != null ? caller.getWindow()
                        : ((mDisplayContent.getImeInputTarget() != null)
                                ? mDisplayContent.getImeInputTarget().getWindowState() : null);
                invokeOnImeRequestedChangedListener(windowState, statsToken);
                invokeOnImeRequestedChangedListener(mDisplayContent.getImeInputTarget(),
                        statsToken);
            } else {
                // TODO(b/329229469) change phase and check cancelled / failed
                ImeTracker.forLogging().onCancelled(statsToken,
@@ -334,32 +330,31 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider {

    void onInputTargetChanged(InputTarget target) {
        if (Flags.refactorInsetsController() && target != null) {
            WindowState targetWin = target.getWindowState();
            InsetsControlTarget imeControlTarget = getControlTarget();
            if (target != imeControlTarget && targetWin != null) {
            if (target != imeControlTarget) {
                // If the targetWin is not the imeControlTarget (=RemoteInsetsControlTarget) let it
                // know about the new requestedVisibleTypes for the IME.
                if (imeControlTarget != null) {
                    imeControlTarget.setImeInputTargetRequestedVisibility(
                            (targetWin.getRequestedVisibleTypes() & WindowInsets.Type.ime()) != 0);
                            (target.getRequestedVisibleTypes() & WindowInsets.Type.ime()) != 0);
                }
            }
        }
    }

    // TODO(b/353463205) check callers to see if we can make statsToken @NonNull
    private void invokeOnImeRequestedChangedListener(WindowState windowState,
    private void invokeOnImeRequestedChangedListener(InsetsTarget insetsTarget,
            @Nullable ImeTracker.Token statsToken) {
        final var imeListener = mDisplayContent.mWmService.mOnImeRequestedChangedListener;
        if (imeListener != null) {
            if (windowState != null) {
            if (insetsTarget != null) {
                ImeTracker.forLogging().onProgress(statsToken,
                        ImeTracker.PHASE_WM_POSTING_CHANGED_IME_VISIBILITY);
                mDisplayContent.mWmService.mH.post(() -> {
                    ImeTracker.forLogging().onProgress(statsToken,
                            ImeTracker.PHASE_WM_INVOKING_IME_REQUESTED_LISTENER);
                    imeListener.onImeRequestedChanged(windowState.mClient.asBinder(),
                            windowState.isRequestedVisible(WindowInsets.Type.ime()), statsToken);
                    imeListener.onImeRequestedChanged(insetsTarget.getWindowToken(),
                            insetsTarget.isRequestedVisible(WindowInsets.Type.ime()), statsToken);
                });
            } else {
                ImeTracker.forLogging().onFailed(statsToken,
@@ -676,7 +671,7 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider {
        return target == mDisplayContent.getImeFallback();
    }

    private boolean isImeInputTarget(@NonNull InsetsControlTarget target) {
    private boolean isImeInputTarget(@NonNull InsetsTarget target) {
        return target == mDisplayContent.getImeInputTarget();
    }

Loading