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

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

Make IMMS#calledWithValidTokenLocked() multi-user aware

With this CL,

  InputMethodManagerService##calledWithValidTokenLocked()

starts taking userId into account.

For single-user IME mode, there must be no user observable behavior
change. for multi-user IME mode, which is

  IMMS#mExperimentalConcurrentMultiUserModeEnabled

enabled environement, this CL enables that IPC-based requests from IME
processes that are associated with visible background users will start
passing the virification.

Bug: 305849394
Test: presubmit
Flag: android.view.inputmethod.concurrent_input_methods
Change-Id: Iddf5dc9a4b866c84a930da9da3d0fd4430063b5c
parent a8fdd28e
Loading
Loading
Loading
Loading
+28 −33
Original line number Diff line number Diff line
@@ -510,16 +510,6 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
    @SharedByAllUsersField
    private final WeakHashMap<IBinder, Boolean> mFocusedWindowPerceptible = new WeakHashMap<>();

    /**
     * The token we have made for the currently active input method, to
     * identify it in the future.
     */
    @GuardedBy("ImfLock.class")
    @Nullable
    IBinder getCurTokenLocked() {
        return getInputMethodBindingController(mCurrentUserId).getCurToken();
    }

    /**
     * The displayId of current active input method.
     */
@@ -1493,14 +1483,16 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
     * Returns true iff the caller is identified to be the current input method with the token.
     *
     * @param token the window token given to the input method when it was started
     * @param userId userId of the calling IME process
     * @return true if and only if non-null valid token is specified
     */
    @GuardedBy("ImfLock.class")
    private boolean calledWithValidTokenLocked(@NonNull IBinder token) {
    private boolean calledWithValidTokenLocked(@NonNull IBinder token, @UserIdInt int userId) {
        if (token == null) {
            throw new InvalidParameterException("token must not be null.");
        }
        if (token != getCurTokenLocked()) {
        final var bindingController = getInputMethodBindingController(userId);
        if (token != bindingController.getCurToken()) {
            Slog.e(TAG, "Ignoring " + Debug.getCaller() + " due to an invalid token."
                    + " uid:" + Binder.getCallingUid() + " token:" + token);
            return false;
@@ -2599,9 +2591,9 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.

    @BinderThread
    private void updateStatusIcon(@NonNull IBinder token, String packageName,
            @DrawableRes int iconId) {
            @DrawableRes int iconId, @UserIdInt int userId) {
        synchronized (ImfLock.class) {
            if (!calledWithValidTokenLocked(token)) {
            if (!calledWithValidTokenLocked(token, userId)) {
                return;
            }
            final long ident = Binder.clearCallingIdentity();
@@ -2743,24 +2735,26 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.

    @BinderThread
    @SuppressWarnings("deprecation")
    private void setImeWindowStatus(@NonNull IBinder token, int vis, int backDisposition) {
    private void setImeWindowStatus(@NonNull IBinder token, int vis, int backDisposition,
            @UserIdInt int userId) {
        final int topFocusedDisplayId = mWindowManagerInternal.getTopFocusedDisplayId();

        synchronized (ImfLock.class) {
            if (!calledWithValidTokenLocked(token)) {
            if (!calledWithValidTokenLocked(token, userId)) {
                return;
            }
            final var bindingController = getInputMethodBindingController(userId);
            // Skip update IME status when current token display is not same as focused display.
            // Note that we still need to update IME status when focusing external display
            // that does not support system decoration and fallback to show IME on default
            // display since it is intentional behavior.
            final int tokenDisplayId = getCurTokenDisplayIdLocked();
            final int tokenDisplayId = bindingController.getCurTokenDisplayId();
            if (tokenDisplayId != topFocusedDisplayId && tokenDisplayId != FALLBACK_DISPLAY_ID) {
                return;
            }
            mImeWindowVis = vis;
            mBackDisposition = backDisposition;
            updateSystemUiLocked(vis, backDisposition);
            updateSystemUiLocked(vis, backDisposition, userId);
        }

        final boolean dismissImeOnBackKeyPressed;
@@ -2780,9 +2774,10 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
    }

    @BinderThread
    private void reportStartInput(@NonNull IBinder token, IBinder startInputToken) {
    private void reportStartInput(@NonNull IBinder token, IBinder startInputToken,
            @UserIdInt int userId) {
        synchronized (ImfLock.class) {
            if (!calledWithValidTokenLocked(token)) {
            if (!calledWithValidTokenLocked(token, userId)) {
                return;
            }
            final IBinder targetWindow = mImeTargetWindowMap.get(startInputToken);
@@ -4048,7 +4043,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
    private void setInputMethod(@NonNull IBinder token, String id, @UserIdInt int userId) {
        final int callingUid = Binder.getCallingUid();
        synchronized (ImfLock.class) {
            if (!calledWithValidTokenLocked(token)) {
            if (!calledWithValidTokenLocked(token, userId)) {
                return;
            }
            final InputMethodSettings settings = InputMethodSettingsRepository.get(mCurrentUserId);
@@ -4066,7 +4061,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
            InputMethodSubtype subtype, @UserIdInt int userId) {
        final int callingUid = Binder.getCallingUid();
        synchronized (ImfLock.class) {
            if (!calledWithValidTokenLocked(token)) {
            if (!calledWithValidTokenLocked(token, userId)) {
                return;
            }
            final InputMethodSettings settings = InputMethodSettingsRepository.get(mCurrentUserId);
@@ -4087,7 +4082,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
    @BinderThread
    private boolean switchToPreviousInputMethod(@NonNull IBinder token, @UserIdInt int userId) {
        synchronized (ImfLock.class) {
            if (!calledWithValidTokenLocked(token)) {
            if (!calledWithValidTokenLocked(token, userId)) {
                return false;
            }
            final var bindingController = getInputMethodBindingController(userId);
@@ -4169,7 +4164,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
    private boolean switchToNextInputMethod(@NonNull IBinder token, boolean onlyCurrentIme,
            @UserIdInt int userId) {
        synchronized (ImfLock.class) {
            if (!calledWithValidTokenLocked(token)) {
            if (!calledWithValidTokenLocked(token, userId)) {
                return false;
            }
            return switchToNextInputMethodLocked(token, onlyCurrentIme, userId);
@@ -4196,7 +4191,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
    private boolean shouldOfferSwitchingToNextInputMethod(@NonNull IBinder token,
            @UserIdInt int userId) {
        synchronized (ImfLock.class) {
            if (!calledWithValidTokenLocked(token)) {
            if (!calledWithValidTokenLocked(token, userId)) {
                return false;
            }
            final var bindingController = getInputMethodBindingController(userId);
@@ -4658,7 +4653,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
        try {
            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.applyImeVisibility");
            synchronized (ImfLock.class) {
                if (!calledWithValidTokenLocked(token)) {
                if (!calledWithValidTokenLocked(token, userId)) {
                    ImeTracker.forLogging().onFailed(statsToken,
                            ImeTracker.PHASE_SERVER_CURRENT_ACTIVE_IME);
                    return;
@@ -4757,7 +4752,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
        try {
            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.hideMySoftInput");
            synchronized (ImfLock.class) {
                if (!calledWithValidTokenLocked(token)) {
                if (!calledWithValidTokenLocked(token, userId)) {
                    ImeTracker.forLogging().onFailed(statsToken,
                            ImeTracker.PHASE_SERVER_CURRENT_ACTIVE_IME);
                    return;
@@ -4796,7 +4791,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
        try {
            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.showMySoftInput");
            synchronized (ImfLock.class) {
                if (!calledWithValidTokenLocked(token)) {
                if (!calledWithValidTokenLocked(token, userId)) {
                    ImeTracker.forLogging().onFailed(statsToken,
                            ImeTracker.PHASE_SERVER_CURRENT_ACTIVE_IME);
                    return;
@@ -6012,7 +6007,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
    private void reportFullscreenMode(@NonNull IBinder token, boolean fullscreen,
            @UserIdInt int userId) {
        synchronized (ImfLock.class) {
            if (!calledWithValidTokenLocked(token)) {
            if (!calledWithValidTokenLocked(token, userId)) {
                return;
            }
            final var userData = getUserData(userId);
@@ -6842,13 +6837,13 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
        @BinderThread
        @Override
        public void setImeWindowStatusAsync(int vis, int backDisposition) {
            mImms.setImeWindowStatus(mToken, vis, backDisposition);
            mImms.setImeWindowStatus(mToken, vis, backDisposition, mUserId);
        }

        @BinderThread
        @Override
        public void reportStartInputAsync(IBinder startInputToken) {
            mImms.reportStartInput(mToken, startInputToken);
            mImms.reportStartInput(mToken, startInputToken, mUserId);
        }

        @BinderThread
@@ -6932,7 +6927,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
        @BinderThread
        @Override
        public void updateStatusIconAsync(String packageName, @DrawableRes int iconId) {
            mImms.updateStatusIcon(mToken, packageName, iconId);
            mImms.updateStatusIcon(mToken, packageName, iconId, mUserId);
        }

        @BinderThread
@@ -6999,7 +6994,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
        @Override
        public void switchKeyboardLayoutAsync(int direction) {
            synchronized (ImfLock.class) {
                if (!mImms.calledWithValidTokenLocked(mToken)) {
                if (!mImms.calledWithValidTokenLocked(mToken, mUserId)) {
                    return;
                }
                final long ident = Binder.clearCallingIdentity();