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

Commit fb7b11b3 authored by Ahaan Ugale's avatar Ahaan Ugale Committed by Automerger Merge Worker
Browse files

Merge "Introduce a default Voice IME concept." into sc-dev am: dadfd22e

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13944370

Change-Id: I756c008620895b4d2593a8a1d7726c3cfb724754
parents 60c3522b dadfd22e
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -6290,6 +6290,20 @@ public final class Settings {
        public static final String SELECTED_INPUT_METHOD_SUBTYPE =
                "selected_input_method_subtype";
        /**
         * The {@link android.view.inputmethod.InputMethodInfo.InputMethodInfo#getId() ID} of the
         * default voice input method.
         * <p>
         * This stores the last known default voice IME. If the related system config value changes,
         * this is reset by InputMethodManagerService.
         * <p>
         * This IME is not necessarily in the enabled IME list. That state is still stored in
         * {@link #ENABLED_INPUT_METHODS}.
         *
         * @hide
         */
        public static final String DEFAULT_VOICE_INPUT_METHOD = "default_voice_input_method";
        /**
         * Setting to record the history of input method subtype, holding the pair of ID of IME
         * and its last used subtype.
+1 −0
Original line number Diff line number Diff line
@@ -296,6 +296,7 @@ message SecureSettingsProto {
        optional SettingProto subtype_history = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
        optional SettingProto selected_input_method_subtype = 6 [ (android.privacy).dest = DEST_AUTOMATIC ];
        optional SettingProto show_ime_with_hard_keyboard = 7 [ (android.privacy).dest = DEST_AUTOMATIC ];
        optional SettingProto default_voice_input_method = 8 [ (android.privacy).dest = DEST_AUTOMATIC ];
    }
    optional InputMethods input_methods = 26;

+3 −0
Original line number Diff line number Diff line
@@ -2150,6 +2150,9 @@ class SettingsProtoDumpUtil {
        dumpSetting(s, p,
                Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD,
                SecureSettingsProto.InputMethods.SHOW_IME_WITH_HARD_KEYBOARD);
        dumpSetting(s, p,
                Settings.Secure.DEFAULT_VOICE_INPUT_METHOD,
                SecureSettingsProto.InputMethods.DEFAULT_VOICE_INPUT_METHOD);
        p.end(inputMethodsToken);

        dumpSetting(s, p,
+34 −0
Original line number Diff line number Diff line
@@ -4830,6 +4830,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
                setInputMethodEnabledLocked(defaultImiId, true);
            }
        }

        updateDefaultVoiceImeIfNeededLocked();

        // Here is not the perfect place to reset the switching controller. Ideally
        // mSwitchingController and mSettings should be able to share the same state.
        // TODO: Make sure that mSwitchingController and mSettings are sharing the
@@ -4842,6 +4845,37 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
                mSettings.getCurrentUserId(), 0 /* unused */, inputMethodList).sendToTarget();
    }

    @GuardedBy("mMethodMap")
    private void updateDefaultVoiceImeIfNeededLocked() {
        final String systemSpeechRecognizer =
                mContext.getString(com.android.internal.R.string.config_systemSpeechRecognizer);
        final String currentDefaultVoiceImeId = mSettings.getDefaultVoiceInputMethod();
        final InputMethodInfo newSystemVoiceIme = InputMethodUtils.chooseSystemVoiceIme(
                mMethodMap, systemSpeechRecognizer, currentDefaultVoiceImeId);
        if (newSystemVoiceIme == null) {
            if (DEBUG) {
                Slog.i(TAG, "Found no valid default Voice IME. If the user is still locked,"
                        + " this may be expected.");
            }
            // Clear DEFAULT_VOICE_INPUT_METHOD when necessary.  Note that InputMethodSettings
            // does not update the actual Secure Settings until the user is unlocked.
            if (!TextUtils.isEmpty(currentDefaultVoiceImeId)) {
                mSettings.putDefaultVoiceInputMethod("");
                // We don't support disabling the voice ime when a package is removed from the
                // config.
            }
            return;
        }
        if (TextUtils.equals(currentDefaultVoiceImeId, newSystemVoiceIme.getId())) {
            return;
        }
        if (DEBUG) {
            Slog.i(TAG, "Enabling the default Voice IME:" + newSystemVoiceIme);
        }
        setInputMethodEnabledLocked(newSystemVoiceIme.getId(), true);
        mSettings.putDefaultVoiceInputMethod(newSystemVoiceIme.getId());
    }

    // ----------------------------------------------------------------------

    private void showInputMethodAndSubtypeEnabler(String inputMethodId) {
+62 −0
Original line number Diff line number Diff line
@@ -337,6 +337,52 @@ final class InputMethodUtils {
        return getDefaultEnabledImes(context, imis, false /* onlyMinimum */);
    }

    /**
     * Chooses an eligible system voice IME from the given IMEs.
     *
     * @param methodMap Map from the IME ID to {@link InputMethodInfo}.
     * @param systemSpeechRecognizerPackageName System speech recognizer configured by the system
     *                                          config.
     * @param currentDefaultVoiceImeId IME ID currently set to
     *                                 {@link Settings.Secure#DEFAULT_VOICE_INPUT_METHOD}
     * @return {@link InputMethodInfo} that is found in {@code methodMap} and most suitable for
     *                                 the system voice IME.
     */
    @Nullable
    static InputMethodInfo chooseSystemVoiceIme(
            @NonNull ArrayMap<String, InputMethodInfo> methodMap,
            @Nullable String systemSpeechRecognizerPackageName,
            @Nullable String currentDefaultVoiceImeId) {
        if (TextUtils.isEmpty(systemSpeechRecognizerPackageName)) {
            return null;
        }
        final InputMethodInfo defaultVoiceIme = methodMap.get(currentDefaultVoiceImeId);
        // If the config matches the package of the setting, use the current one.
        if (defaultVoiceIme != null && defaultVoiceIme.isSystem()
                && defaultVoiceIme.getPackageName().equals(systemSpeechRecognizerPackageName)) {
            return defaultVoiceIme;
        }
        InputMethodInfo firstMatchingIme = null;
        final int methodCount = methodMap.size();
        for (int i = 0; i < methodCount; ++i) {
            final InputMethodInfo imi = methodMap.valueAt(i);
            if (!imi.isSystem()) {
                continue;
            }
            if (!TextUtils.equals(imi.getPackageName(), systemSpeechRecognizerPackageName)) {
                continue;
            }
            if (firstMatchingIme != null) {
                Slog.e(TAG, "At most one InputMethodService can be published in "
                        + "systemSpeechRecognizer: " + systemSpeechRecognizerPackageName
                        + ". Ignoring all of them.");
                return null;
            }
            firstMatchingIme = imi;
        }
        return firstMatchingIme;
    }

    static boolean containsSubtypeOf(InputMethodInfo imi, @Nullable Locale locale,
            boolean checkCountry, String mode) {
        if (locale == null) {
@@ -1233,6 +1279,22 @@ final class InputMethodUtils {
            return imi;
        }

        void putDefaultVoiceInputMethod(String imeId) {
            if (DEBUG) {
                Slog.d(TAG, "putDefaultVoiceInputMethodStr: " + imeId + ", " + mCurrentUserId);
            }
            putString(Settings.Secure.DEFAULT_VOICE_INPUT_METHOD, imeId);
        }

        @Nullable
        String getDefaultVoiceInputMethod() {
            final String imi = getString(Settings.Secure.DEFAULT_VOICE_INPUT_METHOD, null);
            if (DEBUG) {
                Slog.d(TAG, "getDefaultVoiceInputMethodStr: " + imi);
            }
            return imi;
        }

        boolean isSubtypeSelected() {
            return getSelectedInputMethodSubtypeHashCode() != NOT_A_SUBTYPE_ID;
        }
Loading