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

Commit dda53bf0 authored by Seigo Nonaka's avatar Seigo Nonaka Committed by Android (Google) Code Review
Browse files

Merge "Move parseInputMethodsAndSubtypesString to InputMethodUtils."

parents b2043cac 2028ddaa
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
@@ -29,6 +29,9 @@ import android.os.RemoteException;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.text.TextUtils;
import android.text.TextUtils.SimpleStringSplitter;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Pair;
import android.util.Slog;
import android.view.inputmethod.InputMethodInfo;
@@ -61,6 +64,8 @@ public class InputMethodUtils {
    private static final String TAG_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE =
            "EnabledWhenDefaultIsNotAsciiCapable";
    private static final String TAG_ASCII_CAPABLE = "AsciiCapable";
    private static final char INPUT_METHOD_SEPARATOR = ':';
    private static final char INPUT_METHOD_SUBTYPE_SEPARATOR = ';';
    /**
     * Used in {@link #getFallbackLocaleForDefaultIme(ArrayList, Context)} to find the fallback IMEs
     * that are mainly used until the system becomes ready. Note that {@link Locale} in this array
@@ -765,6 +770,40 @@ public class InputMethodUtils {
        }
    }

    /**
     * Parses the setting stored input methods and subtypes string value.
     *
     * @param inputMethodsAndSubtypesString The input method subtypes value stored in settings.
     * @return Map from input method ID to set of input method subtypes IDs.
     */
    @VisibleForTesting
    public static ArrayMap<String, ArraySet<String>> parseInputMethodsAndSubtypesString(
            @Nullable final String inputMethodsAndSubtypesString) {

        final ArrayMap<String, ArraySet<String>> imeMap = new ArrayMap<String, ArraySet<String>>();
        if (TextUtils.isEmpty(inputMethodsAndSubtypesString)) {
            return imeMap;
        }

        final SimpleStringSplitter typeSplitter =
                new SimpleStringSplitter(INPUT_METHOD_SEPARATOR);
        final SimpleStringSplitter subtypeSplitter =
                new SimpleStringSplitter(INPUT_METHOD_SUBTYPE_SEPARATOR);

        List<Pair<String, ArrayList<String>>> allImeSettings =
                InputMethodSettings.buildInputMethodsAndSubtypeList(inputMethodsAndSubtypesString,
                        typeSplitter,
                        subtypeSplitter);
        for (Pair<String, ArrayList<String>> ime : allImeSettings) {
            ArraySet<String> subtypes = new ArraySet<String>();
            if (ime.second != null) {
                subtypes.addAll(ime.second);
            }
            imeMap.put(ime.first, subtypes);
        }
        return imeMap;
    }

    /**
     * Utility class for putting and getting settings for InputMethod
     * TODO: Move all putters and getters of settings to this class.
+128 −1
Original line number Diff line number Diff line
@@ -23,9 +23,11 @@ import android.content.pm.ServiceInfo;
import android.os.Parcel;
import android.test.InstrumentationTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodSubtype;
import android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder;
import android.view.inputmethod.InputMethodSubtype;

import java.util.ArrayList;
import java.util.List;
@@ -947,4 +949,129 @@ public class InputMethodUtilsTest extends InstrumentationTestCase {
            assertEquals(Locale.ENGLISH, locales.get(4));
        }
    }

    public void testParseInputMethodsAndSubtypesString() {
        // Trivial cases.
        {
            assertTrue(InputMethodUtils.parseInputMethodsAndSubtypesString("").isEmpty());
            assertTrue(InputMethodUtils.parseInputMethodsAndSubtypesString(null).isEmpty());
        }

        // No subtype cases.
        {
            ArrayMap<String, ArraySet<String>> r =
                    InputMethodUtils.parseInputMethodsAndSubtypesString("ime0");
            assertEquals(1, r.size());
            assertTrue(r.containsKey("ime0"));
            assertTrue(r.get("ime0").isEmpty());
        }
        {
            ArrayMap<String, ArraySet<String>> r =
                    InputMethodUtils.parseInputMethodsAndSubtypesString("ime0:ime1");
            assertEquals(2, r.size());
            assertTrue(r.containsKey("ime0"));
            assertTrue(r.get("ime0").isEmpty());
            assertTrue(r.containsKey("ime1"));
            assertTrue(r.get("ime1").isEmpty());
        }

        // Input metho IDs and their subtypes.
        {
            ArrayMap<String, ArraySet<String>> r =
                    InputMethodUtils.parseInputMethodsAndSubtypesString("ime0;subtype0");
            assertEquals(1, r.size());
            assertTrue(r.containsKey("ime0"));
            ArraySet<String> subtypes = r.get("ime0");
            assertEquals(1, subtypes.size());
            assertTrue(subtypes.contains("subtype0"));
        }
        {
            ArrayMap<String, ArraySet<String>> r =
                    InputMethodUtils.parseInputMethodsAndSubtypesString("ime0;subtype0;subtype0");
            assertEquals(1, r.size());
            assertTrue(r.containsKey("ime0"));
            ArraySet<String> subtypes = r.get("ime0");
            assertEquals(1, subtypes.size());
            assertTrue(subtypes.contains("subtype0"));
        }
        {
            ArrayMap<String, ArraySet<String>> r =
                    InputMethodUtils.parseInputMethodsAndSubtypesString("ime0;subtype0;subtype1");
            assertEquals(1, r.size());
            assertTrue(r.containsKey("ime0"));
            ArraySet<String> subtypes = r.get("ime0");
            assertEquals(2, subtypes.size());
            assertTrue(subtypes.contains("subtype0"));
            assertTrue(subtypes.contains("subtype1"));
        }
        {
            ArrayMap<String, ArraySet<String>> r =
                    InputMethodUtils.parseInputMethodsAndSubtypesString(
                            "ime0;subtype0:ime1;subtype1");
            assertEquals(2, r.size());
            assertTrue(r.containsKey("ime0"));
            assertTrue(r.containsKey("ime1"));
            ArraySet<String> subtypes0 = r.get("ime0");
            assertEquals(1, subtypes0.size());
            assertTrue(subtypes0.contains("subtype0"));

            ArraySet<String> subtypes1 = r.get("ime1");
            assertEquals(1, subtypes1.size());
            assertTrue(subtypes1.contains("subtype1"));
        }
        {
            ArrayMap<String, ArraySet<String>> r =
                    InputMethodUtils.parseInputMethodsAndSubtypesString(
                            "ime0;subtype0;subtype1:ime1;subtype2");
            assertEquals(2, r.size());
            assertTrue(r.containsKey("ime0"));
            assertTrue(r.containsKey("ime1"));
            ArraySet<String> subtypes0 = r.get("ime0");
            assertEquals(2, subtypes0.size());
            assertTrue(subtypes0.contains("subtype0"));
            assertTrue(subtypes0.contains("subtype1"));

            ArraySet<String> subtypes1 = r.get("ime1");
            assertEquals(1, subtypes1.size());
            assertTrue(subtypes1.contains("subtype2"));
        }
        {
            ArrayMap<String, ArraySet<String>> r =
                    InputMethodUtils.parseInputMethodsAndSubtypesString(
                            "ime0;subtype0;subtype1:ime1;subtype1;subtype2");
            assertEquals(2, r.size());
            assertTrue(r.containsKey("ime0"));
            assertTrue(r.containsKey("ime1"));
            ArraySet<String> subtypes0 = r.get("ime0");
            assertEquals(2, subtypes0.size());
            assertTrue(subtypes0.contains("subtype0"));
            assertTrue(subtypes0.contains("subtype1"));

            ArraySet<String> subtypes1 = r.get("ime1");
            assertEquals(2, subtypes1.size());
            assertTrue(subtypes0.contains("subtype1"));
            assertTrue(subtypes1.contains("subtype2"));
        }
        {
            ArrayMap<String, ArraySet<String>> r =
                    InputMethodUtils.parseInputMethodsAndSubtypesString(
                            "ime0;subtype0;subtype1:ime1;subtype1;subtype2:ime2");
            assertEquals(3, r.size());
            assertTrue(r.containsKey("ime0"));
            assertTrue(r.containsKey("ime1"));
            assertTrue(r.containsKey("ime2"));
            ArraySet<String> subtypes0 = r.get("ime0");
            assertEquals(2, subtypes0.size());
            assertTrue(subtypes0.contains("subtype0"));
            assertTrue(subtypes0.contains("subtype1"));

            ArraySet<String> subtypes1 = r.get("ime1");
            assertEquals(2, subtypes1.size());
            assertTrue(subtypes0.contains("subtype1"));
            assertTrue(subtypes1.contains("subtype2"));

            ArraySet<String> subtypes2 = r.get("ime2");
            assertTrue(subtypes2.isEmpty());
        }
    }
}
+4 −31
Original line number Diff line number Diff line
@@ -145,9 +145,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
    static final boolean DEBUG_RESTORE = DEBUG || false;
    static final String TAG = "InputMethodManagerService";

    private static final char INPUT_METHOD_SEPARATOR = ':';
    private static final char INPUT_METHOD_SUBTYPE_SEPARATOR = ';';

    static final int MSG_SHOW_IM_SUBTYPE_PICKER = 1;
    static final int MSG_SHOW_IM_SUBTYPE_ENABLER = 2;
    static final int MSG_SHOW_IM_CONFIG = 3;
@@ -528,8 +525,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
            Slog.i(TAG, " new=" + newValue);
        }
        // 'new' is the just-restored state, 'prev' is what was in settings prior to the restore
        ArrayMap<String, ArraySet<String>> prevMap = parseInputMethodsAndSubtypesString(prevValue);
        ArrayMap<String, ArraySet<String>> newMap = parseInputMethodsAndSubtypesString(newValue);
        ArrayMap<String, ArraySet<String>> prevMap =
                InputMethodUtils.parseInputMethodsAndSubtypesString(prevValue);
        ArrayMap<String, ArraySet<String>> newMap =
                InputMethodUtils.parseInputMethodsAndSubtypesString(newValue);

        // Merge the restored ime+subtype enabled states into the live state
        for (ArrayMap.Entry<String, ArraySet<String>> entry : newMap.entrySet()) {
@@ -568,32 +567,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
        return InputMethodSettings.buildInputMethodsSettingString(imeMap);
    }

    // TODO: Move this method to InputMethodUtils with adding unit tests.
    static ArrayMap<String, ArraySet<String>> parseInputMethodsAndSubtypesString(
            final String inputMethodsAndSubtypesString) {
        final ArrayMap<String, ArraySet<String>> imeMap = new ArrayMap<>();
        if (TextUtils.isEmpty(inputMethodsAndSubtypesString)) {
            return imeMap;
        }

        final SimpleStringSplitter typeSplitter =
                new SimpleStringSplitter(INPUT_METHOD_SEPARATOR);
        final SimpleStringSplitter subtypeSplitter =
                new SimpleStringSplitter(INPUT_METHOD_SUBTYPE_SEPARATOR);
        List<Pair<String, ArrayList<String>>> allImeSettings =
                InputMethodSettings.buildInputMethodsAndSubtypeList(inputMethodsAndSubtypesString,
                        typeSplitter,
                        subtypeSplitter);
        for (Pair<String, ArrayList<String>> ime : allImeSettings) {
            ArraySet<String> subtypes = new ArraySet<>();
            if (ime.second != null) {
                subtypes.addAll(ime.second);
            }
            imeMap.put(ime.first, subtypes);
        }
        return imeMap;
    }

    class MyPackageMonitor extends PackageMonitor {
        private boolean isChangingPackagesOfCurrentUser() {
            final int userId = getChangingUserId();