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

Commit 8d5731f0 authored by Cosmin Băieș's avatar Cosmin Băieș
Browse files

Cleanup and documentation of ImeTargetWindowState

Following up from the IME layering/input/control target cleanup, this
covers the IME target window on the IMMS side. The name is left more
broad as it represents the target of the InputMethodManagerService,
which will correspond to the IME input target in DisplayContent.

This also passes around some IntDef annotations, and ensures private
ImeTargetWindowState fields are accessed via getters.

Flag: EXEMPT cleanup
Test: atest FrameworksInputMethodSystemServerTests
Bug: 394328311
Change-Id: I50998e59ba78e8778353729bad4f284d0423e6df
parent 6c98bdf2
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -1117,7 +1117,8 @@ public final class InputMethodManager {

    private boolean startInputOnWindowFocusGainInternal(@StartInputReason int startInputReason,
            View focusedView, @StartInputFlags int startInputFlags,
            @SoftInputModeFlags int softInputMode, int windowFlags) {
            @SoftInputModeFlags int softInputMode,
            @WindowManager.LayoutParams.Flags int windowFlags) {
        synchronized (mH) {
            mCurrentEditorInfo = null;
            mCompletions = null;
@@ -3400,7 +3401,8 @@ public final class InputMethodManager {
    @RequiresPermission(value = Manifest.permission.INTERACT_ACROSS_USERS_FULL, conditional = true)
    private boolean startInputInner(@StartInputReason int startInputReason,
            @Nullable IBinder windowGainingFocus, @StartInputFlags int startInputFlags,
            @SoftInputModeFlags int softInputMode, int windowFlags) {
            @SoftInputModeFlags int softInputMode,
            @WindowManager.LayoutParams.Flags int windowFlags) {
        final View view;
        synchronized (mH) {
            view = getServedViewLocked();
@@ -3673,7 +3675,7 @@ public final class InputMethodManager {
            @StartInputFlags int startInputFlags,
            @StartInputReason int startInputReason,
            @SoftInputModeFlags int softInputMode,
            int windowFlags) {
            @WindowManager.LayoutParams.Flags int windowFlags) {
        return (startInputFlags & StartInputFlags.WINDOW_GAINED_FOCUS) == 0
                && (startInputFlags & StartInputFlags.IS_TEXT_EDITOR) == 0
                && previousViewFocusParameters != null
+4 −3
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.view.inputmethod;

import android.annotation.Nullable;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams.SoftInputModeFlags;

import com.android.internal.inputmethod.StartInputFlags;
@@ -34,13 +35,13 @@ final class ViewFocusParameterInfo {
    @StartInputFlags final int mPreviousStartInputFlags;
    @StartInputReason final int mPreviousStartInputReason;
    @SoftInputModeFlags final int mPreviousSoftInputMode;
    final int mPreviousWindowFlags;
    @WindowManager.LayoutParams.Flags final int mPreviousWindowFlags;

    ViewFocusParameterInfo(@Nullable EditorInfo previousEditorInfo,
            @StartInputFlags int previousStartInputFlags,
            @StartInputReason int previousStartInputReason,
            @SoftInputModeFlags int previousSoftInputMode,
            int previousWindowFlags) {
            @WindowManager.LayoutParams.Flags int previousWindowFlags) {
        mPreviousEditorInfo = previousEditorInfo;
        mPreviousStartInputFlags = previousStartInputFlags;
        mPreviousStartInputReason = previousStartInputReason;
@@ -52,7 +53,7 @@ final class ViewFocusParameterInfo {
            @StartInputFlags int startInputFlags,
            @StartInputReason int startInputReason,
            @SoftInputModeFlags int softInputMode,
            int windowFlags) {
            @WindowManager.LayoutParams.Flags int windowFlags) {
        return mPreviousStartInputFlags == startInputFlags
                && mPreviousStartInputReason == startInputReason
                && mPreviousSoftInputMode == softInputMode
+8 −6
Original line number Diff line number Diff line
@@ -128,8 +128,9 @@ final class IInputMethodManagerImpl extends IInputMethodManager.Stub {
        void startInputOrWindowGainedFocusAsync(
                @StartInputReason int startInputReason, IInputMethodClient client,
                IBinder windowToken, @StartInputFlags int startInputFlags,
                @WindowManager.LayoutParams.SoftInputModeFlags int softInputMode, int windowFlags,
                @Nullable EditorInfo editorInfo, IRemoteInputConnection inputConnection,
                @WindowManager.LayoutParams.SoftInputModeFlags int softInputMode,
                @WindowManager.LayoutParams.Flags int windowFlags, @Nullable EditorInfo editorInfo,
                IRemoteInputConnection inputConnection,
                IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
                int unverifiedTargetSdkVersion, @UserIdInt int userId,
                @NonNull ImeOnBackInvokedDispatcher imeDispatcher, boolean imeRequestedVisible,
@@ -138,8 +139,9 @@ final class IInputMethodManagerImpl extends IInputMethodManager.Stub {
        InputBindResult startInputOrWindowGainedFocus(
                @StartInputReason int startInputReason, IInputMethodClient client,
                IBinder windowToken, @StartInputFlags int startInputFlags,
                @WindowManager.LayoutParams.SoftInputModeFlags int softInputMode, int windowFlags,
                @Nullable EditorInfo editorInfo, IRemoteInputConnection inputConnection,
                @WindowManager.LayoutParams.SoftInputModeFlags int softInputMode,
                @WindowManager.LayoutParams.Flags int windowFlags, @Nullable EditorInfo editorInfo,
                IRemoteInputConnection inputConnection,
                IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
                int unverifiedTargetSdkVersion, @UserIdInt int userId,
                @NonNull ImeOnBackInvokedDispatcher imeDispatcher, boolean imeRequestedVisible);
@@ -320,7 +322,7 @@ final class IInputMethodManagerImpl extends IInputMethodManager.Stub {
            @StartInputReason int startInputReason, IInputMethodClient client, IBinder windowToken,
            @StartInputFlags int startInputFlags,
            @WindowManager.LayoutParams.SoftInputModeFlags int softInputMode,
            int windowFlags, @Nullable EditorInfo editorInfo,
            @WindowManager.LayoutParams.Flags int windowFlags, @Nullable EditorInfo editorInfo,
            IRemoteInputConnection inputConnection,
            IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
            int unverifiedTargetSdkVersion, @UserIdInt int userId,
@@ -336,7 +338,7 @@ final class IInputMethodManagerImpl extends IInputMethodManager.Stub {
            IInputMethodClient client, IBinder windowToken,
            @StartInputFlags int startInputFlags,
            @WindowManager.LayoutParams.SoftInputModeFlags int softInputMode,
            int windowFlags, @Nullable EditorInfo editorInfo,
            @WindowManager.LayoutParams.Flags int windowFlags, @Nullable EditorInfo editorInfo,
            IRemoteInputConnection inputConnection,
            IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
            int unverifiedTargetSdkVersion, @UserIdInt int userId,
+3 −3
Original line number Diff line number Diff line
@@ -43,9 +43,9 @@ final class ImeBindingState {
    final int mUserId;

    /**
     * The last window token that we confirmed to be focused. This is always updated upon reports
     * from the input method client. If the window state is already changed before the report is
     * handled, this field just keeps the last value.
     * The token of the last window that we confirmed to be focused. This is always updated upon
     * reports from the input method client. If the window state is already changed before the
     * report is handled, this field just keeps the last value.
     */
    @Nullable
    final IBinder mFocusedWindow;
+97 −72
Original line number Diff line number Diff line
@@ -87,7 +87,7 @@ public final class ImeVisibilityStateComputer {

    /**
     * A map used to track the requested IME target window and its state. The key represents the
     * token of the window and the value is the corresponding IME window state.
     * token of the window and the value is the corresponding IME target window state.
     */
    @GuardedBy("ImfLock.class")
    private final WeakHashMap<IBinder, ImeTargetWindowState> mRequestWindowStateMap =
@@ -134,9 +134,9 @@ public final class ImeVisibilityStateComputer {
    private IBinder mCurVisibleImeInputTarget;

    /**
     * The last window token that we confirmed that IME started talking to.  This is always updated
     * upon reports from the input method.  If the window state is already changed before the report
     * is handled, this field just keeps the last value.
     * The token of the last window that we confirmed that IME started talking to. This is always
     * updated upon reports from the input method. If the window state is already changed before
     * the report is handled, this field just keeps the last value.
     */
    @GuardedBy("ImfLock.class")
    @Nullable
@@ -393,26 +393,28 @@ public final class ImeVisibilityStateComputer {
    ImeTargetWindowState getOrCreateWindowState(IBinder windowToken) {
        ImeTargetWindowState state = mRequestWindowStateMap.get(windowToken);
        if (state == null) {
            state = new ImeTargetWindowState(SOFT_INPUT_STATE_UNSPECIFIED, 0, false, false, false);
            state = new ImeTargetWindowState(SOFT_INPUT_STATE_UNSPECIFIED, 0 /* windowFlags */,
                    false /* imeFocusChanged */, false /* hasFocusedEditor */,
                    false /* isStartInputByWindowGainFocus */, TOOL_TYPE_UNKNOWN);
        }
        return state;
    }

    @GuardedBy("ImfLock.class")
    ImeTargetWindowState getWindowStateOrNull(IBinder windowToken) {
        ImeTargetWindowState state = mRequestWindowStateMap.get(windowToken);
        return state;
    @Nullable
    ImeTargetWindowState getWindowStateOrNull(@Nullable IBinder windowToken) {
        return mRequestWindowStateMap.get(windowToken);
    }

    @GuardedBy("ImfLock.class")
    void setWindowState(IBinder windowToken, @NonNull ImeTargetWindowState newState) {
    void setWindowState(@NonNull IBinder windowToken, @NonNull ImeTargetWindowState newState) {
        final ImeTargetWindowState state = mRequestWindowStateMap.get(windowToken);
        if (state != null && newState.hasEditorFocused() && (
                newState.mToolType != MotionEvent.TOOL_TYPE_STYLUS
                newState.getToolType() != MotionEvent.TOOL_TYPE_STYLUS
                        || Flags.refactorInsetsController())) {
            // Inherit the last requested IME visible state when the target window is still
            // focused with an editor.
            newState.setRequestedImeVisible(state.mRequestedImeVisible);
            newState.setRequestedImeVisible(state.isRequestedImeVisible());
        }
        setWindowStateInner(windowToken, newState);
    }
@@ -442,11 +444,25 @@ public final class ImeVisibilityStateComputer {
        }
    }

    /**
     * Computes the IME visibility state from the given IME target window state.
     *
     * @param state               the state of the IME target window.
     * @param allowVisible        whether the soft input modes
     *                            {@link WindowManager.LayoutParams#SOFT_INPUT_STATE_VISIBLE} and
     *                            {@link WindowManager.LayoutParams#SOFT_INPUT_STATE_ALWAYS_VISIBLE}
     *                            are allowed.
     * @param imeRequestedVisible whether the IME target window has the IME insets type in the
     *                            requestedVisibleTypes (see
     *                            {@link InputMethodManager#hasViewImeRequestedVisible}).
     */
    @GuardedBy("ImfLock.class")
    ImeVisibilityResult computeState(ImeTargetWindowState state, boolean allowVisible,
    @Nullable
    ImeVisibilityResult computeState(@NonNull ImeTargetWindowState state, boolean allowVisible,
            boolean imeRequestedVisible) {
        // TODO: Output the request IME visibility state according to the requested window state
        final int softInputVisibility = state.mSoftInputModeState & SOFT_INPUT_MASK_STATE;
        final var softInputMode = state.getSoftInputModeState();
        final int softInputVisibility = softInputMode & SOFT_INPUT_MASK_STATE;
        // Should we auto-show the IME even if the caller has not
        // specified what should be done with it?
        // We only do this automatically if the window can resize
@@ -455,12 +471,12 @@ public final class ImeVisibilityStateComputer {
        // by the IME) or if running on a large screen where there
        // is more room for the target window + IME.
        final boolean doAutoShow =
                (state.mSoftInputModeState & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST)
                (softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST)
                        == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
                        || mService.mRes.getConfiguration().isLayoutSizeAtLeast(
                        Configuration.SCREENLAYOUT_SIZE_LARGE);
        final boolean isForwardNavigation = (state.mSoftInputModeState
                & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0;
        final boolean isForwardNavigation =
                (softInputMode & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0;

        // We shows the IME when the system allows the IME focused target window to restore the
        // IME visibility (e.g. switching to the app task when last time the IME is visible).
@@ -508,7 +524,7 @@ public final class ImeVisibilityStateComputer {
                // Do nothing but preserving the last IME requested visibility state.
                final ImeTargetWindowState lastState = getWindowStateOrNull(mLastImeTargetWindow);
                if (lastState != null) {
                    state.setRequestedImeVisible(lastState.mRequestedImeVisible);
                    state.setRequestedImeVisible(lastState.isRequestedImeVisible());
                }
                break;
            case WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN:
@@ -570,7 +586,7 @@ public final class ImeVisibilityStateComputer {
            // to rely on this behavior to hide the IME when the editor no longer has focus
            // To maintain compatibility, we are now hiding the IME when we don't have
            // an editor upon refocusing a window.
            if (state.isStartInputByGainFocus()) {
            if (state.isStartInputByWindowGainFocus()) {
                ProtoLog.v(IME_VIS_STATE_COMPUTER_DEBUG,
                        "Same window without editor will hide input");
                return new ImeVisibilityResult(STATE_HIDE_IME_EXPLICIT,
@@ -578,7 +594,7 @@ public final class ImeVisibilityStateComputer {
            }
        }
        if (!state.hasEditorFocused() && (mInputShown || (Flags.refactorInsetsController()
                && imeRequestedVisible)) && state.isStartInputByGainFocus()
                && imeRequestedVisible)) && state.isStartInputByWindowGainFocus()
                && mService.mInputMethodDeviceConfigs.shouldHideImeWhenNoEditorFocus()) {
            // Hide the soft-keyboard when the system do nothing for softInputModeState
            // of the window being gained focus without an editor. This behavior benefits
@@ -760,56 +776,59 @@ public final class ImeVisibilityStateComputer {
    }

    /**
     * A class that represents the current state of the IME target window.
     * State information about an IME target window (i.e. a window for which we started an
     * input connection). One of the IME target windows is set as the current
     * {@link com.android.server.wm.DisplayContent#mImeInputTarget}.
     */
    static class ImeTargetWindowState {

        ImeTargetWindowState(@SoftInputModeFlags int softInputModeState, int windowFlags,
                boolean imeFocusChanged, boolean hasFocusedEditor,
                boolean isStartInputByGainFocus) {
            this(softInputModeState, windowFlags, imeFocusChanged, hasFocusedEditor,
                    isStartInputByGainFocus, TOOL_TYPE_UNKNOWN);
        }

        ImeTargetWindowState(@SoftInputModeFlags int softInputModeState, int windowFlags,
                boolean imeFocusChanged, boolean hasFocusedEditor,
                boolean isStartInputByGainFocus, @MotionEvent.ToolType int toolType) {
        ImeTargetWindowState(@SoftInputModeFlags int softInputModeState,
                @WindowManager.LayoutParams.Flags int windowFlags, boolean imeFocusChanged,
                boolean hasFocusedEditor, boolean isStartInputByWindowGainFocus,
                @MotionEvent.ToolType int toolType) {
            mSoftInputModeState = softInputModeState;
            mWindowFlags = windowFlags;
            mImeFocusChanged = imeFocusChanged;
            mHasFocusedEditor = hasFocusedEditor;
            mIsStartInputByGainFocus = isStartInputByGainFocus;
            mIsStartInputByWindowGainFocus = isStartInputByWindowGainFocus;
            mToolType = toolType;
        }

        /**
         * Visibility state for this window. By default no state has been specified.
         */
        private final @SoftInputModeFlags int mSoftInputModeState;
        /** {@link WindowManager.LayoutParams#softInputMode} of the IME target window. */
        @SoftInputModeFlags
        private final int mSoftInputModeState;

        /** Window flags of the IME target window. */
        @WindowManager.LayoutParams.Flags
        private final int mWindowFlags;

        /**
         * {@link MotionEvent#getToolType(int)} that was used to click editor.
         */
        private final int mToolType;

        /**
         * {@code true} means the IME focus changed from the previous window, {@code false}
         * otherwise.
         */
        /** Whether the IME focus changed from the previous window. */
        private final boolean mImeFocusChanged;

        /**
         * {@code true} when the window has focused an editor, {@code false} otherwise.
         * Whether the window has a focused view that is a text editor.
         *
         * @see android.view.View#onCheckIsTextEditor
         */
        private final boolean mHasFocusedEditor;

        private final boolean mIsStartInputByGainFocus;
        /**
         * Whether this became the IME target (started an input connection) due to the window
         * gaining input focus.
         *
         * @see com.android.internal.inputmethod.StartInputFlags#WINDOW_GAINED_FOCUS
         */
        private final boolean mIsStartInputByWindowGainFocus;

        /**
         * Set if the client has asked for the input method to be shown.
         * The type of tool that was used to click editor.
         *
         * @see MotionEvent#getToolType
         */
        @MotionEvent.ToolType
        private final int mToolType;

        /** Whether the client of the window requested the IME to be visible. */
        @GuardedBy("ImfLock.class")
        private boolean mRequestedImeVisible;

@@ -827,45 +846,38 @@ public final class ImeVisibilityStateComputer {
        private int mImeDisplayId = DEFAULT_DISPLAY;

        @AnyThread
        boolean hasImeFocusChanged() {
            return mImeFocusChanged;
        @SoftInputModeFlags
        int getSoftInputModeState() {
            return mSoftInputModeState;
        }

        @AnyThread
        boolean hasEditorFocused() {
            return mHasFocusedEditor;
        @WindowManager.LayoutParams.Flags
        int getWindowFlags() {
            return mWindowFlags;
        }

        @AnyThread
        boolean isStartInputByGainFocus() {
            return mIsStartInputByGainFocus;
        boolean hasImeFocusChanged() {
            return mImeFocusChanged;
        }

        @AnyThread
        int getSoftInputModeState() {
            return mSoftInputModeState;
        boolean hasEditorFocused() {
            return mHasFocusedEditor;
        }

        @AnyThread
        int getWindowFlags() {
            return mWindowFlags;
        boolean isStartInputByWindowGainFocus() {
            return mIsStartInputByWindowGainFocus;
        }

        @AnyThread
        @MotionEvent.ToolType
        int getToolType() {
            return mToolType;
        }

        @GuardedBy("ImfLock.class")
        private void setImeDisplayId(int imeDisplayId) {
            mImeDisplayId = imeDisplayId;
        }

        @GuardedBy("ImfLock.class")
        int getImeDisplayId() {
            return mImeDisplayId;
        }

        @GuardedBy("ImfLock.class")
        private void setRequestedImeVisible(boolean requestedImeVisible) {
            mRequestedImeVisible = requestedImeVisible;
@@ -877,7 +889,7 @@ public final class ImeVisibilityStateComputer {
        }

        @GuardedBy("ImfLock.class")
        void setRequestImeToken(IBinder token) {
        void setRequestImeToken(@NonNull IBinder token) {
            mRequestImeToken = token;
        }

@@ -886,15 +898,28 @@ public final class ImeVisibilityStateComputer {
            return mRequestImeToken;
        }

        @GuardedBy("ImfLock.class")
        private void setImeDisplayId(int imeDisplayId) {
            mImeDisplayId = imeDisplayId;
        }

        @GuardedBy("ImfLock.class")
        int getImeDisplayId() {
            return mImeDisplayId;
        }

        @Override
        public String toString() {
            return "ImeTargetWindowState{ imeToken " + mRequestImeToken
            return "ImeTargetWindowState{"
                    + " softInputModeState " + softInputModeToString(mSoftInputModeState)
                    + " windowFlags: " + Integer.toHexString(mWindowFlags)
                    + " imeFocusChanged " + mImeFocusChanged
                    + " hasEditorFocused " + mHasFocusedEditor
                    + " hasFocusedEditor " + mHasFocusedEditor
                    + " isStartInputByWindowGainFocus " + mIsStartInputByWindowGainFocus
                    + " toolType: " + mToolType
                    + " requestedImeVisible " + mRequestedImeVisible
                    + " requestImeToken " + mRequestImeToken
                    + " imeDisplayId " + mImeDisplayId
                    + " softInputModeState " + softInputModeToString(mSoftInputModeState)
                    + " isStartInputByGainFocus " + mIsStartInputByGainFocus
                    + "}";
        }
    }
Loading