Merge "Introduce IInputMethodManager.StartInputParams"
diff --git a/core/java/android/inputmethodservice/IInputMethodWrapper.java b/core/java/android/inputmethodservice/IInputMethodWrapper.java
index 8f24172..849690d 100644
--- a/core/java/android/inputmethodservice/IInputMethodWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodWrapper.java
@@ -31,13 +31,11 @@
 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 @@
      *
      * <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 @@
                 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 @@
 
     @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
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index e442e6d..3a87975 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -144,6 +144,7 @@
 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 @@
          */
         @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);
             }
         }
 
diff --git a/core/java/android/view/inputmethod/InputMethod.java b/core/java/android/view/inputmethod/InputMethod.java
index 54ff11c..fc225fe 100644
--- a/core/java/android/view/inputmethod/InputMethod.java
+++ b/core/java/android/view/inputmethod/InputMethod.java
@@ -29,9 +29,9 @@
 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 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);
         }
     }
 
diff --git a/core/java/com/android/internal/inputmethod/IInputMethod.aidl b/core/java/com/android/internal/inputmethod/IInputMethod.aidl
index b819615..88983ce 100644
--- a/core/java/com/android/internal/inputmethod/IInputMethod.aidl
+++ b/core/java/com/android/internal/inputmethod/IInputMethod.aidl
@@ -45,9 +45,16 @@
 
     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);
 
diff --git a/services/core/java/com/android/server/inputmethod/IInputMethodInvoker.java b/services/core/java/com/android/server/inputmethod/IInputMethodInvoker.java
index 4ffad91..5327d0f 100644
--- a/services/core/java/com/android/server/inputmethod/IInputMethodInvoker.java
+++ b/services/core/java/com/android/server/inputmethod/IInputMethodInvoker.java
@@ -148,13 +148,19 @@
     }
 
     @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);
         }