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

Commit a810bd20 authored by Felix Stern's avatar Felix Stern
Browse files

Reset requestedVisibleTypes after returning to window without editor focussed

The IME should not show after retuning to a window if there is no editor focussed, even if the requestedVisibleTypes for that window are set. Formerly, we only reset the requestedVisibleTypes for the IME, if it was shown and no editor focussed.
This CL passes the requested IME visibility when calling startInputOrWindowGainedFocus, so we can take that into account, whether the IME should be hidden.

Fix: 396065313
Flag: android.view.inputmethod.refactor_insets_controller
Test: manual: Open window and show IME
              Open other window on top (both visible); IME should hide
              Remove editorFocus of 1st window
              Close 2nd window; verify IME not showing
Change-Id: Ie20b4f9b83227bf674aeb85059693393cb86e39d
parent 93cc9d2f
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -379,7 +379,7 @@ final class IInputMethodManagerGlobalInvoker {
            @Nullable IRemoteInputConnection remoteInputConnection,
            @Nullable IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
            int unverifiedTargetSdkVersion, @UserIdInt int userId,
            @NonNull ImeOnBackInvokedDispatcher imeDispatcher) {
            @NonNull ImeOnBackInvokedDispatcher imeDispatcher, boolean imeRequestedVisible) {
        final IInputMethodManager service = getService();
        if (service == null) {
            return InputBindResult.NULL;
@@ -388,7 +388,7 @@ final class IInputMethodManagerGlobalInvoker {
            return service.startInputOrWindowGainedFocus(startInputReason, client, windowToken,
                    startInputFlags, softInputMode, windowFlags, editorInfo, remoteInputConnection,
                    remoteAccessibilityInputConnection, unverifiedTargetSdkVersion, userId,
                    imeDispatcher);
                    imeDispatcher, imeRequestedVisible);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
@@ -408,7 +408,8 @@ final class IInputMethodManagerGlobalInvoker {
            @Nullable IRemoteInputConnection remoteInputConnection,
            @Nullable IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
            int unverifiedTargetSdkVersion, @UserIdInt int userId,
            @NonNull ImeOnBackInvokedDispatcher imeDispatcher, boolean useAsyncShowHideMethod) {
            @NonNull ImeOnBackInvokedDispatcher imeDispatcher, boolean imeRequestedVisible,
            boolean useAsyncShowHideMethod) {
        final IInputMethodManager service = getService();
        if (service == null) {
            return -1;
@@ -417,7 +418,8 @@ final class IInputMethodManagerGlobalInvoker {
            service.startInputOrWindowGainedFocusAsync(startInputReason, client, windowToken,
                    startInputFlags, softInputMode, windowFlags, editorInfo, remoteInputConnection,
                    remoteAccessibilityInputConnection, unverifiedTargetSdkVersion, userId,
                    imeDispatcher, advanceAngGetStartInputSequenceNumber(), useAsyncShowHideMethod);
                    imeDispatcher, imeRequestedVisible, advanceAngGetStartInputSequenceNumber(),
                    useAsyncShowHideMethod);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
+28 −10
Original line number Diff line number Diff line
@@ -871,6 +871,19 @@ public final class InputMethodManager {
        IInputMethodManagerGlobalInvoker.reportPerceptibleAsync(windowToken, perceptible);
    }

    private static boolean hasViewImeRequestedVisible(View view) {
        // before the refactor, the requestedVisibleTypes for the IME were not in sync with
        // the state that was actually requested.
        if (Flags.refactorInsetsController() && view != null) {
            final var controller = view.getWindowInsetsController();
            if (controller != null) {
                return (view.getWindowInsetsController()
                        .getRequestedVisibleTypes() & WindowInsets.Type.ime()) != 0;
            }
        }
        return false;
    }

    private final class DelegateImpl implements
            ImeFocusController.InputMethodManagerDelegate {

@@ -941,6 +954,9 @@ public final class InputMethodManager {
                    Log.v(TAG, "Reporting focus gain, without startInput");
                }

                final boolean imeRequestedVisible = hasViewImeRequestedVisible(
                        mCurRootView.getView());

                // ignore the result
                Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMM.startInputOrWindowGainedFocus");
                IInputMethodManagerGlobalInvoker.startInputOrWindowGainedFocus(
@@ -950,7 +966,7 @@ public final class InputMethodManager {
                        null,
                        null, null,
                        mCurRootView.mContext.getApplicationInfo().targetSdkVersion,
                        UserHandle.myUserId(), mImeDispatcher);
                        UserHandle.myUserId(), mImeDispatcher, imeRequestedVisible);
                Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
            }
        }
@@ -2441,9 +2457,8 @@ public final class InputMethodManager {
                    ImeTracker.forLogging().onProgress(statsToken,
                            ImeTracker.PHASE_CLIENT_NO_ONGOING_USER_ANIMATION);
                    if (resultReceiver != null) {
                        final boolean imeReqVisible =
                                (viewRootImpl.getInsetsController().getRequestedVisibleTypes()
                                        & WindowInsets.Type.ime()) != 0;
                        final boolean imeReqVisible = hasViewImeRequestedVisible(
                                viewRootImpl.getView());
                        resultReceiver.send(
                                imeReqVisible ? InputMethodManager.RESULT_UNCHANGED_SHOWN
                                        : InputMethodManager.RESULT_SHOWN, null);
@@ -2656,9 +2671,8 @@ public final class InputMethodManager {
                    ImeTracker.forLogging().onProgress(statsToken,
                            ImeTracker.PHASE_CLIENT_VIEW_HANDLER_AVAILABLE);

                    final boolean imeReqVisible =
                            (viewRootImpl.getInsetsController().getRequestedVisibleTypes()
                                    & WindowInsets.Type.ime()) != 0;
                    final boolean imeReqVisible = hasViewImeRequestedVisible(
                            viewRootImpl.getView());
                    if (resultReceiver != null) {
                        resultReceiver.send(
                                !imeReqVisible ? InputMethodManager.RESULT_UNCHANGED_HIDDEN
@@ -3412,6 +3426,7 @@ public final class InputMethodManager {
        final Handler icHandler;
        InputBindResult res = null;
        final boolean hasServedView;
        final boolean imeRequestedVisible;
        synchronized (mH) {
            // Now that we are locked again, validate that our state hasn't
            // changed.
@@ -3479,10 +3494,13 @@ public final class InputMethodManager {
            }
            mServedInputConnection = servedInputConnection;

            imeRequestedVisible = hasViewImeRequestedVisible(servedView);

            if (DEBUG) {
                Log.v(TAG, "START INPUT: view=" + InputMethodDebug.dumpViewInfo(view)
                        + " ic=" + ic + " editorInfo=" + editorInfo + " startInputFlags="
                        + InputMethodDebug.startInputFlagsToString(startInputFlags));
                        + InputMethodDebug.startInputFlagsToString(startInputFlags)
                        + " imeRequestedVisible=" + imeRequestedVisible);
            }

            // When we switch between non-editable views, do not call into the IMMS.
@@ -3513,7 +3531,7 @@ public final class InputMethodManager {
                        servedInputConnection == null ? null
                                : servedInputConnection.asIRemoteAccessibilityInputConnection(),
                        view.getContext().getApplicationInfo().targetSdkVersion, targetUserId,
                        mImeDispatcher, mAsyncShowHideMethodEnabled);
                        mImeDispatcher, imeRequestedVisible, mAsyncShowHideMethodEnabled);
            } else {
                res = IInputMethodManagerGlobalInvoker.startInputOrWindowGainedFocus(
                        startInputReason, mClient, windowGainingFocus, startInputFlags,
@@ -3521,7 +3539,7 @@ public final class InputMethodManager {
                        servedInputConnection == null ? null
                                : servedInputConnection.asIRemoteAccessibilityInputConnection(),
                        view.getContext().getApplicationInfo().targetSdkVersion, targetUserId,
                        mImeDispatcher);
                        mImeDispatcher, imeRequestedVisible);
            }
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
            if (Flags.useZeroJankProxy()) {
+4 −4
Original line number Diff line number Diff line
@@ -105,7 +105,7 @@ interface IInputMethodManager {
            in @nullable EditorInfo editorInfo, in @nullable IRemoteInputConnection inputConnection,
            in @nullable IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
            int unverifiedTargetSdkVersion, int userId,
            in ImeOnBackInvokedDispatcher imeDispatcher);
            in ImeOnBackInvokedDispatcher imeDispatcher, boolean imeRequestedVisible);

    // If windowToken is null, this just does startInput().  Otherwise this reports that a window
    // has gained focus, and if 'editorInfo' is non-null then also does startInput.
@@ -120,8 +120,8 @@ interface IInputMethodManager {
            in @nullable EditorInfo editorInfo, in @nullable IRemoteInputConnection inputConnection,
            in @nullable IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
            int unverifiedTargetSdkVersion, int userId,
            in ImeOnBackInvokedDispatcher imeDispatcher, int startInputSeq,
            boolean useAsyncShowHideMethod);
            in ImeOnBackInvokedDispatcher imeDispatcher, boolean imeRequestedVisible,
            int startInputSeq, boolean useAsyncShowHideMethod);

    void showInputMethodPickerFromClient(in IInputMethodClient client,
            int auxiliarySubtypeMode);
+9 −9
Original line number Diff line number Diff line
@@ -132,8 +132,8 @@ final class IInputMethodManagerImpl extends IInputMethodManager.Stub {
                @Nullable EditorInfo editorInfo, IRemoteInputConnection inputConnection,
                IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
                int unverifiedTargetSdkVersion, @UserIdInt int userId,
                @NonNull ImeOnBackInvokedDispatcher imeDispatcher, int startInputSeq,
                boolean useAsyncShowHideMethod);
                @NonNull ImeOnBackInvokedDispatcher imeDispatcher, boolean imeRequestedVisible,
                int startInputSeq, boolean useAsyncShowHideMethod);

        InputBindResult startInputOrWindowGainedFocus(
                @StartInputReason int startInputReason, IInputMethodClient client,
@@ -142,7 +142,7 @@ final class IInputMethodManagerImpl extends IInputMethodManager.Stub {
                @Nullable EditorInfo editorInfo, IRemoteInputConnection inputConnection,
                IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
                int unverifiedTargetSdkVersion, @UserIdInt int userId,
                @NonNull ImeOnBackInvokedDispatcher imeDispatcher);
                @NonNull ImeOnBackInvokedDispatcher imeDispatcher, boolean imeRequestedVisible);

        void showInputMethodPickerFromClient(IInputMethodClient client, int auxiliarySubtypeMode);

@@ -324,11 +324,11 @@ final class IInputMethodManagerImpl extends IInputMethodManager.Stub {
            IRemoteInputConnection inputConnection,
            IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
            int unverifiedTargetSdkVersion, @UserIdInt int userId,
            @NonNull ImeOnBackInvokedDispatcher imeDispatcher) {
            @NonNull ImeOnBackInvokedDispatcher imeDispatcher, boolean imeRequestedVisible) {
        return mCallback.startInputOrWindowGainedFocus(
                startInputReason, client, windowToken, startInputFlags, softInputMode,
                windowFlags, editorInfo, inputConnection, remoteAccessibilityInputConnection,
                unverifiedTargetSdkVersion, userId, imeDispatcher);
                unverifiedTargetSdkVersion, userId, imeDispatcher, imeRequestedVisible);
    }

    @Override
@@ -340,13 +340,13 @@ final class IInputMethodManagerImpl extends IInputMethodManager.Stub {
            IRemoteInputConnection inputConnection,
            IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
            int unverifiedTargetSdkVersion, @UserIdInt int userId,
            @NonNull ImeOnBackInvokedDispatcher imeDispatcher, int startInputSeq,
            boolean useAsyncShowHideMethod) {
            @NonNull ImeOnBackInvokedDispatcher imeDispatcher, boolean imeRequestedVisible,
            int startInputSeq, boolean useAsyncShowHideMethod) {
        mCallback.startInputOrWindowGainedFocusAsync(
                startInputReason, client, windowToken, startInputFlags, softInputMode,
                windowFlags, editorInfo, inputConnection, remoteAccessibilityInputConnection,
                unverifiedTargetSdkVersion, userId, imeDispatcher, startInputSeq,
                useAsyncShowHideMethod);
                unverifiedTargetSdkVersion, userId, imeDispatcher, imeRequestedVisible,
                startInputSeq, useAsyncShowHideMethod);
    }

    @Override
+4 −2
Original line number Diff line number Diff line
@@ -441,7 +441,8 @@ public final class ImeVisibilityStateComputer {
    }

    @GuardedBy("ImfLock.class")
    ImeVisibilityResult computeState(ImeTargetWindowState state, boolean allowVisible) {
    ImeVisibilityResult computeState(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;
        // Should we auto-show the IME even if the caller has not
@@ -570,7 +571,8 @@ public final class ImeVisibilityStateComputer {
                        SoftInputShowHideReason.HIDE_SAME_WINDOW_FOCUSED_WITHOUT_EDITOR);
            }
        }
        if (!state.hasEditorFocused() && mInputShown && state.isStartInputByGainFocus()
        if (!state.hasEditorFocused() && (mInputShown || (Flags.refactorInsetsController()
                && imeRequestedVisible)) && state.isStartInputByGainFocus()
                && 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
Loading