Merge "Move parseInputMethodsAndSubtypesString to InputMethodUtils."
diff --git a/core/java/com/android/internal/inputmethod/InputMethodUtils.java b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
index d53efa0..191b5a7 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodUtils.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
@@ -29,6 +29,9 @@
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 @@
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
@@ -766,6 +771,40 @@
}
/**
+ * 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.
*/
diff --git a/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodUtilsTest.java b/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodUtilsTest.java
index 67f87a3..e2077a3 100644
--- a/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodUtilsTest.java
+++ b/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodUtilsTest.java
@@ -23,9 +23,11 @@
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 @@
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());
+ }
+ }
}
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index f9f617e..66a2308 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -145,9 +145,6 @@
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 @@
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 @@
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();