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

Commit bb00fe95 authored by Yohei Yukawa's avatar Yohei Yukawa
Browse files

Introduce IInputMethodManager.StartInputParams

IInputMethod#startInput() is a hot-spot where we keep adding new
parameters recently.  Introducing a dedicated parameter object would
allow us to add further parameters with fewer lines of changes.

This CL also renames

  InputMethod#dispatchStartInputWithToken

to

  InputMethod#dispatchStartInput

for consistency.

This is a mechanical refactoring. There should be no developer
observable behavior change.

Bug: 234882948
Test: presubmit
Change-Id: I4a6af9a47db04335921a7d14efe91bfeff25c56d
parent 55b543e1
Loading
Loading
Loading
Loading
+13 −30
Original line number Diff line number Diff line
@@ -31,13 +31,11 @@ import android.os.ResultReceiver;
import android.util.Log;
import android.view.InputChannel;
import android.view.MotionEvent;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputBinding;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethod;
import android.view.inputmethod.InputMethodSession;
import android.view.inputmethod.InputMethodSubtype;
import android.window.ImeOnBackInvokedDispatcher;

import com.android.internal.inputmethod.CancellationGroup;
import com.android.internal.inputmethod.IInlineSuggestionsRequestCallback;
@@ -98,9 +96,9 @@ class IInputMethodWrapper extends IInputMethod.Stub
     *
     * <p>This field must be set and cleared only from the binder thread(s), where the system
     * guarantees that {@link #bindInput(InputBinding)},
     * {@link #startInput(IBinder, IRemoteInputConnection, int, EditorInfo, boolean, boolean)}, and
     * {@link #unbindInput()} are called with the same order as the original calls
     * in {@link com.android.server.inputmethod.InputMethodManagerService}.
     * {@link #startInput(IInputMethod.StartInputParams)}, and {@link #unbindInput()} are called
     * with the same order as the original calls in
     * {@link com.android.server.inputmethod.InputMethodManagerService}.
     * See {@link IBinder#FLAG_ONEWAY} for detailed semantics.</p>
     */
    @Nullable
@@ -194,16 +192,10 @@ class IInputMethodWrapper extends IInputMethod.Stub
                return;
            case DO_START_INPUT: {
                final SomeArgs args = (SomeArgs) msg.obj;
                final IBinder startInputToken = (IBinder) args.arg1;
                final InputConnection ic = (InputConnection) args.arg2;
                final EditorInfo info = (EditorInfo) args.arg3;
                final ImeOnBackInvokedDispatcher imeDispatcher =
                        (ImeOnBackInvokedDispatcher) args.arg4;
                final boolean restarting = args.argi1 == 1;
                @InputMethodNavButtonFlags
                final int navButtonFlags = args.argi2;
                inputMethod.dispatchStartInputWithToken(ic, info, restarting, startInputToken,
                        navButtonFlags, imeDispatcher);
                final InputConnection inputConnection = (InputConnection) args.arg1;
                final IInputMethod.StartInputParams params =
                        (IInputMethod.StartInputParams) args.arg2;
                inputMethod.dispatchStartInput(inputConnection, params);
                args.recycle();
                return;
            }
@@ -345,28 +337,19 @@ class IInputMethodWrapper extends IInputMethod.Stub

    @BinderThread
    @Override
    public void startInput(IBinder startInputToken, IRemoteInputConnection inputConnection,
            EditorInfo editorInfo, boolean restarting,
            @InputMethodNavButtonFlags int navButtonFlags,
            @NonNull ImeOnBackInvokedDispatcher imeDispatcher) {
    public void startInput(@NonNull IInputMethod.StartInputParams params) {
        if (mCancellationGroup == null) {
            Log.e(TAG, "startInput must be called after bindInput.");
            mCancellationGroup = new CancellationGroup();
        }

        editorInfo.makeCompatible(mTargetSdkVersion);
        params.editorInfo.makeCompatible(mTargetSdkVersion);

        final InputConnection ic = inputConnection == null ? null
                : new RemoteInputConnection(mTarget, inputConnection, mCancellationGroup);
        final InputConnection ic = params.remoteInputConnection == null ? null
                : new RemoteInputConnection(mTarget, params.remoteInputConnection,
                        mCancellationGroup);

        final SomeArgs args = SomeArgs.obtain();
        args.arg1 = startInputToken;
        args.arg2 = ic;
        args.arg3 = editorInfo;
        args.argi1 = restarting ? 1 : 0;
        args.argi2 = navButtonFlags;
        args.arg4 = imeDispatcher;
        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_START_INPUT, args));
        mCaller.executeOrSendMessage(mCaller.obtainMessageOO(DO_START_INPUT, ic, params));
    }

    @BinderThread
+10 −11
Original line number Diff line number Diff line
@@ -144,6 +144,7 @@ import android.window.WindowMetricsHelper;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.inputmethod.IInlineSuggestionsRequestCallback;
import com.android.internal.inputmethod.IInputContentUriToken;
import com.android.internal.inputmethod.IInputMethod;
import com.android.internal.inputmethod.IInputMethodPrivilegedOperations;
import com.android.internal.inputmethod.IRemoteInputConnection;
import com.android.internal.inputmethod.ImeTracing;
@@ -821,25 +822,23 @@ public class InputMethodService extends AbstractInputMethodService {
         */
        @MainThread
        @Override
        public final void dispatchStartInputWithToken(@Nullable InputConnection inputConnection,
                @NonNull EditorInfo editorInfo, boolean restarting,
                @NonNull IBinder startInputToken, @InputMethodNavButtonFlags int navButtonFlags,
                @NonNull ImeOnBackInvokedDispatcher imeDispatcher) {
            mPrivOps.reportStartInputAsync(startInputToken);
            mNavigationBarController.onNavButtonFlagsChanged(navButtonFlags);
            if (restarting) {
                restartInput(inputConnection, editorInfo);
        public final void dispatchStartInput(@Nullable InputConnection inputConnection,
                @NonNull IInputMethod.StartInputParams params) {
            mPrivOps.reportStartInputAsync(params.startInputToken);
            mNavigationBarController.onNavButtonFlagsChanged(params.navigationBarFlags);
            if (params.restarting) {
                restartInput(inputConnection, params.editorInfo);
            } else {
                startInput(inputConnection, editorInfo);
                startInput(inputConnection, params.editorInfo);
            }
            // Update the IME dispatcher last, so that the previously registered back callback
            // (if any) can be unregistered using the old dispatcher if {@link #doFinishInput()}
            // is called from {@link #startInput(InputConnection, EditorInfo)} or
            // {@link #restartInput(InputConnection, EditorInfo)}.
            mImeDispatcher = imeDispatcher;
            mImeDispatcher = params.imeDispatcher;
            if (mWindow != null) {
                mWindow.getOnBackInvokedDispatcher().setImeOnBackInvokedDispatcher(
                        imeDispatcher);
                        params.imeDispatcher);
            }
        }

+12 −29
Original line number Diff line number Diff line
@@ -29,9 +29,9 @@ import android.util.Log;
import android.view.InputChannel;
import android.view.MotionEvent;
import android.view.View;
import android.window.ImeOnBackInvokedDispatcher;

import com.android.internal.inputmethod.IInlineSuggestionsRequestCallback;
import com.android.internal.inputmethod.IInputMethod;
import com.android.internal.inputmethod.IInputMethodPrivilegedOperations;
import com.android.internal.inputmethod.InlineSuggestionsRequestInfo;
import com.android.internal.inputmethod.InputMethodNavButtonFlags;
@@ -210,47 +210,30 @@ public interface InputMethod {
    public void restartInput(InputConnection inputConnection, EditorInfo editorInfo);

    /**
     * This method is called when {@code {@link #startInput(InputConnection, EditorInfo)} or
     * {@code {@link #restartInput(InputConnection, EditorInfo)} needs to be dispatched.
     * This method is called when {@link #startInput(InputConnection, EditorInfo)} or
     * {@link #restartInput(InputConnection, EditorInfo)} needs to be dispatched.
     *
     * <p>Note: This method is hidden because the {@code startInputToken} that this method is
     * dealing with is one of internal details, which should not be exposed to the IME developers.
     * If you override this method, you are responsible for not breaking existing IMEs that expect
     * <p>Note: This method is hidden because {@link IInputMethod.StartInputParams} is an internal
     * details, which should not be exposed to the IME developers. If you override this method, you
     * are responsible for not breaking existing IMEs that expect
     * {@link #startInput(InputConnection, EditorInfo)} to be still called back.</p>
     *
     * @param inputConnection optional specific input connection for communicating with the text
     *                        box; if {@code null}, you should use the generic bound input
     *                        connection
     * @param editorInfo information about the text box (typically, an EditText) that requests input
     * @param restarting {@code false} if this corresponds to
     *                   {@link #startInput(InputConnection, EditorInfo)}. Otherwise this
     *                   corresponds to {@link #restartInput(InputConnection, EditorInfo)}.
     * @param startInputToken a token that identifies a logical session that starts with this method
     *                        call. Some internal IPCs such as {@link
     *                        InputMethodManager#setImeWindowStatus(IBinder, IBinder, int, int)}
     *                        require this token to work, and you have to keep the token alive until
     *                        the next {@link #startInput(InputConnection, EditorInfo, IBinder)} as
     *                        long as your implementation of {@link InputMethod} relies on such
     *                        IPCs
     * @param navButtonFlags {@link InputMethodNavButtonFlags} in the initial state of this session.
     * @param imeDispatcher The {@link ImeOnBackInvokedDispatcher} to be set on the
     *                      IME's {@link android.window.WindowOnBackInvokedDispatcher}, so that IME
     *                      {@link android.window.OnBackInvokedCallback}s can be forwarded to
     *                      the client requesting to start input.
     * @param params Raw object of {@link IInputMethod.StartInputParams}.
     * @see #startInput(InputConnection, EditorInfo)
     * @see #restartInput(InputConnection, EditorInfo)
     * @see EditorInfo
     * @hide
     */
    @MainThread
    default void dispatchStartInputWithToken(@Nullable InputConnection inputConnection,
            @NonNull EditorInfo editorInfo, boolean restarting,
            @NonNull IBinder startInputToken, @InputMethodNavButtonFlags int navButtonFlags,
            @NonNull ImeOnBackInvokedDispatcher imeDispatcher) {
        if (restarting) {
            restartInput(inputConnection, editorInfo);
    default void dispatchStartInput(@Nullable InputConnection inputConnection,
            @NonNull IInputMethod.StartInputParams params) {
        if (params.restarting) {
            restartInput(inputConnection, params.editorInfo);
        } else {
            startInput(inputConnection, editorInfo);
            startInput(inputConnection, params.editorInfo);
        }
    }

+10 −3
Original line number Diff line number Diff line
@@ -45,9 +45,16 @@ oneway interface IInputMethod {

    void unbindInput();

    void startInput(in IBinder startInputToken, in IRemoteInputConnection inputConnection,
            in EditorInfo editorInfo, boolean restarting, int navigationBarFlags,
            in ImeOnBackInvokedDispatcher imeDispatcher);
    parcelable StartInputParams {
        IBinder startInputToken;
        IRemoteInputConnection remoteInputConnection;
        EditorInfo editorInfo;
        boolean restarting;
        int navigationBarFlags;
        ImeOnBackInvokedDispatcher imeDispatcher;
    }

    void startInput(in StartInputParams params);

    void onNavButtonFlagsChanged(int navButtonFlags);

+9 −3
Original line number Diff line number Diff line
@@ -148,13 +148,19 @@ final class IInputMethodInvoker {
    }

    @AnyThread
    void startInput(IBinder startInputToken, IRemoteInputConnection inputConnection,
    void startInput(IBinder startInputToken, IRemoteInputConnection remoteInputConnection,
            EditorInfo editorInfo, boolean restarting,
            @InputMethodNavButtonFlags int navButtonFlags,
            @NonNull ImeOnBackInvokedDispatcher imeDispatcher) {
        final IInputMethod.StartInputParams params = new IInputMethod.StartInputParams();
        params.startInputToken = startInputToken;
        params.remoteInputConnection = remoteInputConnection;
        params.editorInfo = editorInfo;
        params.restarting = restarting;
        params.navigationBarFlags = navButtonFlags;
        params.imeDispatcher = imeDispatcher;
        try {
            mTarget.startInput(startInputToken, inputConnection, editorInfo, restarting,
                    navButtonFlags, imeDispatcher);
            mTarget.startInput(params);
        } catch (RemoteException e) {
            logRemoteException(e);
        }