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

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

IMM#hideSoftInputFromWindow: Post on handler thread if needed

Also, adding some more ImeTracker phases for better draggability in case of cancelling a request, because of missing the servedView, view's handler, or reposting to our thread.

Test: atest android.autofillservice.cts.dialog.LoginActivityTest#testShowFillDialog_onlyShowOnce
Fix: 374215831
Flag: android.view.inputmethod.refactor_insets_controller
Change-Id: I02e833561b89311a3fe3606e14fe6283efe5cb48
parent 7875655e
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -220,6 +220,7 @@ public interface ImeTracker {
            PHASE_WM_POSTING_CHANGED_IME_VISIBILITY,
            PHASE_WM_INVOKING_IME_REQUESTED_LISTENER,
            PHASE_CLIENT_ALREADY_HIDDEN,
            PHASE_CLIENT_VIEW_HANDLER_AVAILABLE,
    })
    @Retention(RetentionPolicy.SOURCE)
    @interface Phase {}
@@ -424,6 +425,11 @@ public interface ImeTracker {
            ImeProtoEnums.PHASE_WM_INVOKING_IME_REQUESTED_LISTENER;
    /** IME is requested to be hidden, but already hidden. Don't hide to avoid another animation. */
    int PHASE_CLIENT_ALREADY_HIDDEN = ImeProtoEnums.PHASE_CLIENT_ALREADY_HIDDEN;
    /**
     * The view's handler is needed to check if we're running on a different thread. We can't
     * continue without.
     */
    int PHASE_CLIENT_VIEW_HANDLER_AVAILABLE = ImeProtoEnums.PHASE_CLIENT_VIEW_HANDLER_AVAILABLE;

    /**
     * Called when an IME request is started.
+20 −1
Original line number Diff line number Diff line
@@ -2591,6 +2591,17 @@ public final class InputMethodManager {
                // TODO(b/322992891) handle case of HIDE_IMPLICIT_ONLY
                final var viewRootImpl = servedView.getViewRootImpl();
                if (viewRootImpl != null) {
                    Handler vh = servedView.getHandler();
                    if (vh == null) {
                        // If the view doesn't have a handler, something has changed out from
                        // under us. The current input has been closed before (from checkFocus).
                        ImeTracker.forLogging().onFailed(statsToken,
                                ImeTracker.PHASE_CLIENT_VIEW_HANDLER_AVAILABLE);
                        return false;
                    }
                    ImeTracker.forLogging().onProgress(statsToken,
                            ImeTracker.PHASE_CLIENT_VIEW_HANDLER_AVAILABLE);

                    if (resultReceiver != null) {
                        final boolean imeReqVisible =
                                (viewRootImpl.getInsetsController().getRequestedVisibleTypes()
@@ -2599,8 +2610,16 @@ public final class InputMethodManager {
                                !imeReqVisible ? InputMethodManager.RESULT_UNCHANGED_HIDDEN
                                        : InputMethodManager.RESULT_HIDDEN, null);
                    }
                    if (vh.getLooper() != Looper.myLooper()) {
                        // The view is running on a different thread than our own, so
                        // we need to reschedule our work for over there.
                        if (DEBUG) Log.v(TAG, "Hiding soft input: reschedule to view thread");
                        vh.post(() -> viewRootImpl.getInsetsController().hide(
                                WindowInsets.Type.ime()));
                    } else {
                        viewRootImpl.getInsetsController().hide(WindowInsets.Type.ime());
                    }
                }
                return true;
            } else {
                return IInputMethodManagerGlobalInvoker.hideSoftInput(mClient, windowToken,