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

Commit 407aa0ce authored by Felix Stern's avatar Felix Stern
Browse files

Not dispatching another show request to IMS if already shown

With the changes in [1], client visibility is updated at the beginning of a hide animation, but in ImeInsetsSourceProvider#invokeOnImeRequestedChangedListener, we still invoke the listener with visible=true (as the IME is currently animating). This will call IMS with a show request, although the request is eventually cancelled.
However, to not invoke a redundant show request, we can check if another show request was previously triggered, and early return in that case.

[1]: Ibd4b0c43450681b526ca4ed8a79fcb7fa5f2ad2c

Fix: 326377046
Flag: android.view.inputmethod.report_animating_insets_types
Test: atest KeyboardVisibilityControlTest#testImeNoShowSoftInputCallDuringHideAnimation
Test: atest KeyboardVisibilityControlTest#testImeState_AlwaysHidden_EditorDialogLostFocusAfterUnlocked
Test: atest FocusHandlingTest#testMultiWindowFocusHandleOnDifferentUiThread
Test: atest ImeSwitchingTest#testImeUnboundAfterSwitchingWithoutInputFocus
Change-Id: Ib04023b5391b07fb829329ae1683efd63f98d358
parent f6a4d285
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -234,6 +234,7 @@ public interface ImeTracker {
            PHASE_CLIENT_ON_CONTROLS_CHANGED,
            PHASE_SERVER_IME_INVOKER,
            PHASE_SERVER_CLIENT_INVOKER,
            PHASE_SERVER_ALREADY_VISIBLE,
    })
    @Retention(RetentionPolicy.SOURCE)
    @interface Phase {}
@@ -479,6 +480,9 @@ public interface ImeTracker {
    int PHASE_SERVER_IME_INVOKER = ImeProtoEnums.PHASE_SERVER_IME_INVOKER;
    /** Reached the IME client invoker on the server. */
    int PHASE_SERVER_CLIENT_INVOKER = ImeProtoEnums.PHASE_SERVER_CLIENT_INVOKER;
    /** The server will dispatch the show request to the IME, but this is already visible. */
    int PHASE_SERVER_ALREADY_VISIBLE =
            ImeProtoEnums.PHASE_SERVER_ALREADY_VISIBLE;

    /**
     * Called when an IME request is started.
+5 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import android.util.EventLog;
import android.util.Slog;
import android.view.Display;
import android.view.WindowManager;
import android.view.inputmethod.Flags;
import android.view.inputmethod.InputMethod;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
@@ -512,6 +513,10 @@ final class InputMethodBindingController {

    @GuardedBy("ImfLock.class")
    private void clearCurMethodAndSessions() {
        if (Flags.reportAnimatingInsetsTypes()) {
            final var userData = mService.getUserData(mUserId);
            userData.mVisibilityStateComputer.setInputShown(false);
        }
        mService.clearClientSessionsLocked(this);
        mCurMethod = null;
        mCurMethodUid = Process.INVALID_UID;
+6 −0
Original line number Diff line number Diff line
@@ -3519,6 +3519,12 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
        }
        ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_SERVER_SYSTEM_READY);

        if (Flags.reportAnimatingInsetsTypes() && visibilityStateComputer.isInputShown()) {
            // We already called showSoftInput on the IME, no need to dispatch a new show request.
            ImeTracker.forLogging().onCancelled(statsToken,
                    ImeTracker.PHASE_SERVER_ALREADY_VISIBLE);
            return false;
        }
        visibilityStateComputer.requestImeVisibility(windowToken, true);

        // Ensure binding the connection when IME is going to show.