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

Commit 769e7472 authored by Yohei Yukawa's avatar Yohei Yukawa
Browse files

Move IMMS#mCurrentSubtype to binding controller

With this CL IMMS#mCurrentSubtype becomes per-user.

The observable semantics should remain unchanged.

Fix: 346658341
Test: presubmit
Flag: EXEMPT refactor
Change-Id: Ibcc39212ead12c2897f8f52cb9f15b1d39959f71
parent ba21fa88
Loading
Loading
Loading
Loading
+24 −0
Original line number Original line Diff line number Diff line
@@ -46,6 +46,7 @@ import android.view.WindowManager;
import android.view.inputmethod.InputMethod;
import android.view.inputmethod.InputMethod;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InputMethodSubtype;


import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting;
@@ -84,6 +85,7 @@ final class InputMethodBindingController {
    @GuardedBy("ImfLock.class") @Nullable private IInputMethodInvoker mCurMethod;
    @GuardedBy("ImfLock.class") @Nullable private IInputMethodInvoker mCurMethod;
    @GuardedBy("ImfLock.class") private int mCurMethodUid = Process.INVALID_UID;
    @GuardedBy("ImfLock.class") private int mCurMethodUid = Process.INVALID_UID;
    @GuardedBy("ImfLock.class") @Nullable private IBinder mCurToken;
    @GuardedBy("ImfLock.class") @Nullable private IBinder mCurToken;
    @GuardedBy("ImfLock.class") @Nullable private InputMethodSubtype mCurrentSubtype;
    @GuardedBy("ImfLock.class") private int mCurTokenDisplayId = INVALID_DISPLAY;
    @GuardedBy("ImfLock.class") private int mCurTokenDisplayId = INVALID_DISPLAY;
    @GuardedBy("ImfLock.class") private int mCurSeq;
    @GuardedBy("ImfLock.class") private int mCurSeq;
    @GuardedBy("ImfLock.class") private boolean mVisibleBound;
    @GuardedBy("ImfLock.class") private boolean mVisibleBound;
@@ -216,6 +218,28 @@ final class InputMethodBindingController {
        return mCurToken;
        return mCurToken;
    }
    }


    /**
     * The current {@link InputMethodSubtype} of the current input method.
     *
     * @return the current {@link InputMethodSubtype} of the current input method. {@code null}
     *         means that there is no {@link InputMethodSubtype} currently selected
     */
    @GuardedBy("ImfLock.class")
    @Nullable
    InputMethodSubtype getCurrentSubtype() {
        return mCurrentSubtype;
    }

    /**
     * Sets the current {@link InputMethodSubtype} of the current input method.
     *
     * @param currentSubtype the current {@link InputMethodSubtype} of the current input method
     */
    @GuardedBy("ImfLock.class")
    void setCurrentSubtype(@Nullable InputMethodSubtype currentSubtype) {
        mCurrentSubtype = currentSubtype;
    }

    /**
    /**
     * Returns the displayId associated with {@link #getCurToken()}.
     * Returns the displayId associated with {@link #getCurToken()}.
     *
     *
+41 −33
Original line number Original line Diff line number Diff line
@@ -568,12 +568,6 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
    @Nullable
    @Nullable
    EditorInfo mCurEditorInfo;
    EditorInfo mCurEditorInfo;


    /**
     * The current subtype of the current input method.
     */
    @MultiUserUnawareField
    private InputMethodSubtype mCurrentSubtype;

    /**
    /**
     * Map of window perceptible states indexed by their associated window tokens.
     * Map of window perceptible states indexed by their associated window tokens.
     *
     *
@@ -1055,7 +1049,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
                    // one now available?
                    // one now available?
                    changed = chooseNewDefaultIMELocked();
                    changed = chooseNewDefaultIMELocked();
                } else if (!changed && isPackageModified(curIm.getPackageName())) {
                } else if (!changed && isPackageModified(curIm.getPackageName())) {
                    // Even if the current input method is still available, mCurrentSubtype could
                    // Even if the current input method is still available, current subtype could
                    // be obsolete when the package is modified in practice.
                    // be obsolete when the package is modified in practice.
                    changed = true;
                    changed = true;
                }
                }
@@ -3102,7 +3096,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
                notifyInputMethodSubtypeChangedLocked(userId, info, null);
                notifyInputMethodSubtypeChangedLocked(userId, info, null);
                return;
                return;
            }
            }
            final InputMethodSubtype oldSubtype = mCurrentSubtype;
            final InputMethodSubtype oldSubtype = bindingController.getCurrentSubtype();
            final InputMethodSubtype newSubtype;
            final InputMethodSubtype newSubtype;
            if (subtypeId >= 0 && subtypeId < subtypeCount) {
            if (subtypeId >= 0 && subtypeId < subtypeCount) {
                newSubtype = info.getSubtypeAt(subtypeId);
                newSubtype = info.getSubtypeAt(subtypeId);
@@ -4114,7 +4108,9 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
            if (!calledWithValidTokenLocked(token)) {
            if (!calledWithValidTokenLocked(token)) {
                return false;
                return false;
            }
            }
            final InputMethodSettings settings = InputMethodSettingsRepository.get(mCurrentUserId);
            final int userId = mCurrentUserId;
            final var bindingController = getInputMethodBindingController(userId);
            final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
            final Pair<String, String> lastIme = settings.getLastInputMethodAndSubtype();
            final Pair<String, String> lastIme = settings.getLastInputMethodAndSubtype();
            final InputMethodInfo lastImi;
            final InputMethodInfo lastImi;
            if (lastIme != null) {
            if (lastIme != null) {
@@ -4122,13 +4118,15 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
            } else {
            } else {
                lastImi = null;
                lastImi = null;
            }
            }
            final var currentSubtype = bindingController.getCurrentSubtype();
            String targetLastImiId = null;
            String targetLastImiId = null;
            int subtypeId = NOT_A_SUBTYPE_ID;
            int subtypeId = NOT_A_SUBTYPE_ID;
            if (lastIme != null && lastImi != null) {
            if (lastIme != null && lastImi != null) {
                final boolean imiIdIsSame = lastImi.getId().equals(getSelectedMethodIdLocked());
                final boolean imiIdIsSame = lastImi.getId().equals(
                        bindingController.getSelectedMethodId());
                final int lastSubtypeHash = Integer.parseInt(lastIme.second);
                final int lastSubtypeHash = Integer.parseInt(lastIme.second);
                final int currentSubtypeHash = mCurrentSubtype == null ? NOT_A_SUBTYPE_ID
                final int currentSubtypeHash = currentSubtype == null ? NOT_A_SUBTYPE_ID
                        : mCurrentSubtype.hashCode();
                        : currentSubtype.hashCode();
                // If the last IME is the same as the current IME and the last subtype is not
                // If the last IME is the same as the current IME and the last subtype is not
                // defined, there is no need to switch to the last IME.
                // defined, there is no need to switch to the last IME.
                if (!imiIdIsSame || lastSubtypeHash != currentSubtypeHash) {
                if (!imiIdIsSame || lastSubtypeHash != currentSubtypeHash) {
@@ -4138,7 +4136,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
            }
            }


            if (TextUtils.isEmpty(targetLastImiId)
            if (TextUtils.isEmpty(targetLastImiId)
                    && !InputMethodUtils.canAddToLastInputMethod(mCurrentSubtype)) {
                    && !InputMethodUtils.canAddToLastInputMethod(currentSubtype)) {
                // This is a safety net. If the currentSubtype can't be added to the history
                // This is a safety net. If the currentSubtype can't be added to the history
                // and the framework couldn't find the last ime, we will make the last ime be
                // and the framework couldn't find the last ime, we will make the last ime be
                // the most applicable enabled keyboard subtype of the system imes.
                // the most applicable enabled keyboard subtype of the system imes.
@@ -4146,11 +4144,11 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
                if (enabled != null) {
                if (enabled != null) {
                    final int enabledCount = enabled.size();
                    final int enabledCount = enabled.size();
                    final String locale;
                    final String locale;
                    if (mCurrentSubtype != null
                    if (currentSubtype != null
                            && !TextUtils.isEmpty(mCurrentSubtype.getLocale())) {
                            && !TextUtils.isEmpty(currentSubtype.getLocale())) {
                        locale = mCurrentSubtype.getLocale();
                        locale = currentSubtype.getLocale();
                    } else {
                    } else {
                        locale = SystemLocaleWrapper.get(mCurrentUserId).get(0).toString();
                        locale = SystemLocaleWrapper.get(userId).get(0).toString();
                    }
                    }
                    for (int i = 0; i < enabledCount; ++i) {
                    for (int i = 0; i < enabledCount; ++i) {
                        final InputMethodInfo imi = enabled.get(i);
                        final InputMethodInfo imi = enabled.get(i);
@@ -4198,9 +4196,10 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
    @GuardedBy("ImfLock.class")
    @GuardedBy("ImfLock.class")
    private boolean switchToNextInputMethodLocked(@Nullable IBinder token, boolean onlyCurrentIme) {
    private boolean switchToNextInputMethodLocked(@Nullable IBinder token, boolean onlyCurrentIme) {
        final int userId = mCurrentUserId;
        final int userId = mCurrentUserId;
        final var currentImi = getInputMethodBindingController(userId).getSelectedMethod();
        final var bindingController = getInputMethodBindingController(userId);
        final var currentImi = bindingController.getSelectedMethod();
        final ImeSubtypeListItem nextSubtype = mSwitchingController.getNextInputMethodLocked(
        final ImeSubtypeListItem nextSubtype = mSwitchingController.getNextInputMethodLocked(
                onlyCurrentIme, currentImi, mCurrentSubtype);
                onlyCurrentIme, currentImi, bindingController.getCurrentSubtype());
        if (nextSubtype == null) {
        if (nextSubtype == null) {
            return false;
            return false;
        }
        }
@@ -4216,9 +4215,10 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
                return false;
                return false;
            }
            }
            final int userId = mCurrentUserId;
            final int userId = mCurrentUserId;
            final var currentImi = getInputMethodBindingController(userId).getSelectedMethod();
            final var bindingController = getInputMethodBindingController(userId);
            final var currentImi = bindingController.getSelectedMethod();
            final ImeSubtypeListItem nextSubtype = mSwitchingController.getNextInputMethodLocked(
            final ImeSubtypeListItem nextSubtype = mSwitchingController.getNextInputMethodLocked(
                    false /* onlyCurrentIme */, currentImi, mCurrentSubtype);
                    false /* onlyCurrentIme */, currentImi, bindingController.getCurrentSubtype());
            return nextSubtype != null;
            return nextSubtype != null;
        }
        }
    }
    }
@@ -4650,12 +4650,14 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
                }
                }
                return;
                return;
            }
            }
            if (mCurrentUserId != mSwitchingController.getUserId()) {
            final int userId = mCurrentUserId;
            if (userId != mSwitchingController.getUserId()) {
                return;
                return;
            }
            }
            final var imi = getInputMethodBindingController(mCurrentUserId).getSelectedMethod();
            final var imi = getInputMethodBindingController(userId).getSelectedMethod();
            if (imi != null) {
            if (imi != null) {
                mSwitchingController.onUserActionLocked(imi, mCurrentSubtype);
                mSwitchingController.onUserActionLocked(imi,
                        getInputMethodBindingController(userId).getCurrentSubtype());
            }
            }
        }
        }
    }
    }
@@ -5442,9 +5444,11 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
    @GuardedBy("ImfLock.class")
    @GuardedBy("ImfLock.class")
    private void setSelectedInputMethodAndSubtypeLocked(InputMethodInfo imi, int subtypeId,
    private void setSelectedInputMethodAndSubtypeLocked(InputMethodInfo imi, int subtypeId,
            boolean setSubtypeOnly) {
            boolean setSubtypeOnly) {
        final InputMethodSettings settings = InputMethodSettingsRepository.get(mCurrentUserId);
        final int userId = mCurrentUserId;
        final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);
        final var bindingController = getInputMethodBindingController(userId);
        settings.saveCurrentInputMethodAndSubtypeToHistory(getSelectedMethodIdLocked(),
        settings.saveCurrentInputMethodAndSubtypeToHistory(getSelectedMethodIdLocked(),
                mCurrentSubtype);
                bindingController.getCurrentSubtype());


        // Set Subtype here
        // Set Subtype here
        final int newSubtypeHashcode;
        final int newSubtypeHashcode;
@@ -5465,9 +5469,9 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
                newSubtype = getCurrentInputMethodSubtypeLocked();
                newSubtype = getCurrentInputMethodSubtypeLocked();
            }
            }
        }
        }
        mCurrentSubtype = newSubtype;
        settings.putSelectedSubtype(newSubtypeHashcode);
        settings.putSelectedSubtype(newSubtypeHashcode);
        notifyInputMethodSubtypeChangedLocked(settings.getUserId(), imi, mCurrentSubtype);
        bindingController.setCurrentSubtype(newSubtype);
        notifyInputMethodSubtypeChangedLocked(settings.getUserId(), imi, newSubtype);


        if (!setSubtypeOnly) {
        if (!setSubtypeOnly) {
            // Set InputMethod here
            // Set InputMethod here
@@ -5555,9 +5559,11 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.
        if (imi == null || imi.getSubtypeCount() == 0) {
        if (imi == null || imi.getSubtypeCount() == 0) {
            return null;
            return null;
        }
        }
        mCurrentSubtype = SubtypeUtils.getCurrentInputMethodSubtype(imi, settings,
        final var bindingController = getInputMethodBindingController(userId);
                mCurrentSubtype);
        final var subtype = SubtypeUtils.getCurrentInputMethodSubtype(imi, settings,
        return mCurrentSubtype;
                bindingController.getCurrentSubtype());
        bindingController.setCurrentSubtype(subtype);
        return subtype;
    }
    }


    /**
    /**
@@ -5623,14 +5629,16 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl.


    @GuardedBy("ImfLock.class")
    @GuardedBy("ImfLock.class")
    private void switchKeyboardLayoutLocked(int direction) {
    private void switchKeyboardLayoutLocked(int direction) {
        final InputMethodSettings settings = InputMethodSettingsRepository.get(mCurrentUserId);
        final int userId = mCurrentUserId;
        final InputMethodSettings settings = InputMethodSettingsRepository.get(userId);


        final InputMethodInfo currentImi = settings.getMethodMap().get(getSelectedMethodIdLocked());
        final InputMethodInfo currentImi = settings.getMethodMap().get(getSelectedMethodIdLocked());
        if (currentImi == null) {
        if (currentImi == null) {
            return;
            return;
        }
        }
        final var bindingController = getInputMethodBindingController(userId);
        final InputMethodSubtypeHandle currentSubtypeHandle =
        final InputMethodSubtypeHandle currentSubtypeHandle =
                InputMethodSubtypeHandle.of(currentImi, mCurrentSubtype);
                InputMethodSubtypeHandle.of(currentImi, bindingController.getCurrentSubtype());
        final InputMethodSubtypeHandle nextSubtypeHandle =
        final InputMethodSubtypeHandle nextSubtypeHandle =
                mHardwareKeyboardShortcutController.onSubtypeSwitch(currentSubtypeHandle,
                mHardwareKeyboardShortcutController.onSubtypeSwitch(currentSubtypeHandle,
                        direction > 0);
                        direction > 0);