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

Commit 9fdc4569 authored by Nikolas Havrikov's avatar Nikolas Havrikov
Browse files

Extract and move binding visibly to controller

This CL flips the order of events:
Now the IMMS first performs the "visible" binding,
and only then showSoftInput gets called on the IME.

Bug: 205676419
Test: make
Change-Id: I5c29f880cd5eefd0998891012588774de25c55a7
parent 19f60889
Loading
Loading
Loading
Loading
+39 −3
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import android.os.Trace;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.ArrayMap;
import android.util.EventLog;
import android.util.Slog;
import android.view.IWindowManager;
import android.view.WindowManager;
@@ -49,6 +50,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.inputmethod.InputBindResult;
import com.android.internal.inputmethod.UnbindReason;
import com.android.internal.view.IInputMethod;
import com.android.server.EventLogTags;
import com.android.server.wm.WindowManagerInternal;

/**
@@ -442,7 +444,7 @@ final class InputMethodBindingController {
    }

    @GuardedBy("mMethodMap")
    void unbindMainConnectionLocked() {
    private void unbindMainConnectionLocked() {
        mContext.unbindService(mMainConnection);
        mHasConnection = false;
    }
@@ -464,17 +466,51 @@ final class InputMethodBindingController {
    }

    @GuardedBy("mMethodMap")
    boolean bindCurrentInputMethodServiceVisibleConnectionLocked() {
    private boolean bindCurrentInputMethodServiceVisibleConnectionLocked() {
        mVisibleBound = bindCurrentInputMethodServiceLocked(mVisibleConnection,
                IME_VISIBLE_BIND_FLAGS);
        return mVisibleBound;
    }

    @GuardedBy("mMethodMap")
    boolean bindCurrentInputMethodServiceMainConnectionLocked() {
    private boolean bindCurrentInputMethodServiceMainConnectionLocked() {
        mHasConnection = bindCurrentInputMethodServiceLocked(mMainConnection,
                mImeConnectionBindFlags);
        return mHasConnection;
    }

    /**
     * Bind the IME so that it can be shown.
     *
     * <p>
     * Performs a rebind if no binding is achieved in {@link #TIME_TO_RECONNECT} milliseconds.
     */
    @GuardedBy("mMethodMap")
    void setCurrentMethodVisibleLocked() {
        if (mCurMethod != null) {
            if (DEBUG) Slog.d(TAG, "setCurrentMethodVisibleLocked: mCurToken=" + mCurToken);
            if (mHasConnection && !mVisibleBound) {
                bindCurrentInputMethodServiceVisibleConnectionLocked();
            }
            return;
        }

        long bindingDuration = SystemClock.uptimeMillis() - mLastBindTime;
        if (mHasConnection && bindingDuration >= TIME_TO_RECONNECT) {
            // The client has asked to have the input method shown, but
            // we have been sitting here too long with a connection to the
            // service and no interface received, so let's disconnect/connect
            // to try to prod things along.
            EventLog.writeEvent(EventLogTags.IMF_FORCE_RECONNECT_IME, getSelectedMethodId(),
                    bindingDuration, 1);
            Slog.w(TAG, "Force disconnect/connect to the IME in setCurrentMethodVisibleLocked()");
            unbindMainConnectionLocked();
            bindCurrentInputMethodServiceMainConnectionLocked();
        } else {
            if (DEBUG) {
                Slog.d(TAG, "Can't show input: connection = " + mHasConnection + ", time = "
                        + (TIME_TO_RECONNECT - bindingDuration));
            }
        }
    }
}
+5 −27
Original line number Diff line number Diff line
@@ -3046,42 +3046,20 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
            return false;
        }

        boolean res = false;
        IInputMethod curMethod = getCurMethod();
        if (curMethod != null) {
            if (DEBUG) Slog.d(TAG, "showCurrentInputLocked: mCurToken=" + getCurToken());
        mBindingController.setCurrentMethodVisibleLocked();
        if (getCurMethod() != null) {
            // create a placeholder token for IMS so that IMS cannot inject windows into client app.
            Binder showInputToken = new Binder();
            mShowRequestWindowMap.put(showInputToken, windowToken);
            IInputMethod curMethod = getCurMethod();
            executeOrSendMessage(curMethod, mCaller.obtainMessageIIOOO(MSG_SHOW_SOFT_INPUT,
                    getImeShowFlagsLocked(), reason, curMethod, resultReceiver,
                    showInputToken));
            mInputShown = true;
            if (hasConnection() && !isVisibleBound()) {
                mBindingController.bindCurrentInputMethodServiceVisibleConnectionLocked();
            }
            res = true;
        } else {
            long bindingDuration = SystemClock.uptimeMillis() - getLastBindTime();
            if (hasConnection() && bindingDuration >= TIME_TO_RECONNECT) {
                // The client has asked to have the input method shown, but
                // we have been sitting here too long with a connection to the
                // service and no interface received, so let's disconnect/connect
                // to try to prod things along.
                EventLog.writeEvent(EventLogTags.IMF_FORCE_RECONNECT_IME, getSelectedMethodId(),
                        bindingDuration, 1);
                Slog.w(TAG, "Force disconnect/connect to the IME in showCurrentInputLocked()");
                mBindingController.unbindMainConnectionLocked();
                mBindingController.bindCurrentInputMethodServiceMainConnectionLocked();
            } else {
                if (DEBUG) {
                    Slog.d(TAG, "Can't show input: connection = " + hasConnection() + ", time = "
                            + (TIME_TO_RECONNECT - bindingDuration));
                }
            }
            return true;
        }

        return res;
        return false;
    }

    @Override