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

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

Let startInputOrWindowGainedFocus() take userId

This CL lets

  IInputMethodManager#startInputOrWindowGainedFocus()

take the useId as an explicit input parameter for consistency with
other IPC methods that are annotated with

  @RequiresPermission(
      value = INTERACT_ACROSS_USERS_FULL,
      conditional = true).

Doing so enables us to

 1. easily assume that INTERACT_ACROSS_USERS_FULL is necessary only
    when userId parameter is different from the calling user ID.
 2. place caller verification at the beginning of
      InputMethodManagerService#startInputOrWindowGainedFocus()
    like we do so in other Binder IPC methods.

There should be no semantic change in this CL.  This CL is purely for
better readability.

Bug: 34886274
Bug: 237316307
Test: presubmit
Change-Id: I2755fd1f2425f1c0186d46a8e4d62995c8283050
parent 324b546a
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -139,11 +139,13 @@ final class IInputMethodManagerInvoker {
            @WindowManager.LayoutParams.Flags int windowFlags, @Nullable EditorInfo editorInfo,
            @Nullable IRemoteInputConnection remoteInputConnection,
            @Nullable IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
            int unverifiedTargetSdkVersion, @NonNull ImeOnBackInvokedDispatcher imeDispatcher) {
            int unverifiedTargetSdkVersion, @UserIdInt int userId,
            @NonNull ImeOnBackInvokedDispatcher imeDispatcher) {
        try {
            return mTarget.startInputOrWindowGainedFocus(startInputReason, client, windowToken,
                    startInputFlags, softInputMode, windowFlags, editorInfo, remoteInputConnection,
                    remoteAccessibilityInputConnection, unverifiedTargetSdkVersion, imeDispatcher);
                    remoteAccessibilityInputConnection, unverifiedTargetSdkVersion, userId,
                    imeDispatcher);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
+8 −5
Original line number Diff line number Diff line
@@ -285,9 +285,10 @@ public final class InputMethodManager {
    private static final String SUBTYPE_MODE_VOICE = "voice";

    /**
     * Provide this to {@link IInputMethodManager#startInputOrWindowGainedFocus(
     * int, IInputMethodClient, IBinder, int, int, int, EditorInfo,
     * com.android.internal.inputmethod.IRemoteInputConnection, int)} to receive
     * Provide this to {@link IInputMethodManagerInvoker#startInputOrWindowGainedFocus(int,
     * IInputMethodClient, IBinder, int, int, int, EditorInfo,
     * com.android.internal.inputmethod.IRemoteInputConnection, IRemoteAccessibilityInputConnection,
     * int, int, ImeOnBackInvokedDispatcher)} to receive
     * {@link android.window.OnBackInvokedCallback} registrations from IME.
     */
    private final ImeOnBackInvokedDispatcher mImeDispatcher =
@@ -790,7 +791,7 @@ public final class InputMethodManager {
                        null,
                        null, null,
                        mCurRootView.mContext.getApplicationInfo().targetSdkVersion,
                        mImeDispatcher);
                        UserHandle.myUserId(), mImeDispatcher);
            }
        }

@@ -2437,12 +2438,14 @@ public final class InputMethodManager {
                }
                return false;
            }
            final int targetUserId = editorInfo.targetInputMethodUser != null
                    ? editorInfo.targetInputMethodUser.getIdentifier() : UserHandle.myUserId();
            res = mServiceInvoker.startInputOrWindowGainedFocus(
                    startInputReason, mClient, windowGainingFocus, startInputFlags,
                    softInputMode, windowFlags, editorInfo, servedInputConnection,
                    servedInputConnection == null ? null
                            : servedInputConnection.asIRemoteAccessibilityInputConnection(),
                    view.getContext().getApplicationInfo().targetSdkVersion,
                    view.getContext().getApplicationInfo().targetSdkVersion, targetUserId,
                    mImeDispatcher);
            if (DEBUG) Log.v(TAG, "Starting input: Bind result=" + res);
            if (res == null) {
+2 −1
Original line number Diff line number Diff line
@@ -72,7 +72,8 @@ interface IInputMethodManager {
            /* @android.view.WindowManager.LayoutParams.Flags */ int windowFlags,
            in @nullable EditorInfo editorInfo, in @nullable IRemoteInputConnection inputConnection,
            in @nullable IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
            int unverifiedTargetSdkVersion, in ImeOnBackInvokedDispatcher imeDispatcher);
            int unverifiedTargetSdkVersion, int userId,
            in ImeOnBackInvokedDispatcher imeDispatcher);

    void showInputMethodPickerFromClient(in IInputMethodClient client,
            int auxiliarySubtypeMode);
+21 −21
Original line number Diff line number Diff line
@@ -3574,8 +3574,18 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
            int windowFlags, @Nullable EditorInfo editorInfo,
            IRemoteInputConnection inputConnection,
            IRemoteAccessibilityInputConnection remoteAccessibilityInputConnection,
            int unverifiedTargetSdkVersion,
            int unverifiedTargetSdkVersion, @UserIdInt int userId,
            @NonNull ImeOnBackInvokedDispatcher imeDispatcher) {
        if (UserHandle.getCallingUserId() != userId) {
            mContext.enforceCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);

            if (editorInfo == null || editorInfo.targetInputMethodUser == null
                    || editorInfo.targetInputMethodUser.getIdentifier() != userId) {
                throw new InvalidParameterException("EditorInfo#targetInputMethodUser must also be "
                        + "specified for cross-user startInputOrWindowGainedFocus()");
            }
        }

        if (windowToken == null) {
            Slog.e(TAG, "windowToken cannot be null.");
            return InputBindResult.NULL;
@@ -3585,26 +3595,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
                    "IMMS.startInputOrWindowGainedFocus");
            ImeTracing.getInstance().triggerManagerServiceDump(
                    "InputMethodManagerService#startInputOrWindowGainedFocus");
            final int callingUserId = UserHandle.getCallingUserId();
            final int userId;
            if (editorInfo != null && editorInfo.targetInputMethodUser != null
                    && editorInfo.targetInputMethodUser.getIdentifier() != callingUserId) {
                mContext.enforceCallingPermission(
                        Manifest.permission.INTERACT_ACROSS_USERS_FULL,
                        "Using EditorInfo.targetInputMethodUser requires"
                                + " INTERACT_ACROSS_USERS_FULL.");
                userId = editorInfo.targetInputMethodUser.getIdentifier();
                if (!mUserManagerInternal.isUserRunning(userId)) {
                    // There is a chance that we hit here because of race condition. Let's just
                    // return an error code instead of crashing the caller process, which at
                    // least has INTERACT_ACROSS_USERS_FULL permission thus is likely to be an
                    // important process.
                    Slog.e(TAG, "User #" + userId + " is not running.");
                    return InputBindResult.INVALID_USER;
                }
            } else {
                userId = callingUserId;
            }
            final InputBindResult result;
            synchronized (ImfLock.class) {
                final long ident = Binder.clearCallingIdentity();
@@ -3653,9 +3643,19 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
                    + " softInputMode=" + InputMethodDebug.softInputModeToString(softInputMode)
                    + " windowFlags=#" + Integer.toHexString(windowFlags)
                    + " unverifiedTargetSdkVersion=" + unverifiedTargetSdkVersion
                    + " userId=" + userId
                    + " imeDispatcher=" + imeDispatcher);
        }

        if (!mUserManagerInternal.isUserRunning(userId)) {
            // There is a chance that we hit here because of race condition. Let's just
            // return an error code instead of crashing the caller process, which at
            // least has INTERACT_ACROSS_USERS_FULL permission thus is likely to be an
            // important process.
            Slog.w(TAG, "User #" + userId + " is not running.");
            return InputBindResult.INVALID_USER;
        }

        final ClientState cs = mClients.get(client.asBinder());
        if (cs == null) {
            throw new IllegalArgumentException("unknown client " + client.asBinder());