diff options
Diffstat (limited to 'java/src/com/android/inputmethod/latin/Utils.java')
-rw-r--r-- | java/src/com/android/inputmethod/latin/Utils.java | 398 |
1 files changed, 1 insertions, 397 deletions
diff --git a/java/src/com/android/inputmethod/latin/Utils.java b/java/src/com/android/inputmethod/latin/Utils.java index a8679e07a..f8dd5ae42 100644 --- a/java/src/com/android/inputmethod/latin/Utils.java +++ b/java/src/com/android/inputmethod/latin/Utils.java @@ -19,7 +19,6 @@ package com.android.inputmethod.latin; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; -import android.content.res.Resources; import android.inputmethodservice.InputMethodService; import android.net.Uri; import android.os.AsyncTask; @@ -27,19 +26,9 @@ import android.os.Environment; import android.os.Handler; import android.os.HandlerThread; import android.os.Process; -import android.text.InputType; import android.text.TextUtils; import android.text.format.DateUtils; import android.util.Log; -import android.view.inputmethod.EditorInfo; - -import com.android.inputmethod.compat.InputMethodInfoCompatWrapper; -import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; -import com.android.inputmethod.compat.InputMethodSubtypeCompatWrapper; -import com.android.inputmethod.compat.InputTypeCompatUtils; -import com.android.inputmethod.keyboard.Keyboard; -import com.android.inputmethod.keyboard.KeyboardId; -import com.android.inputmethod.latin.define.JniLibName; import java.io.BufferedReader; import java.io.File; @@ -51,20 +40,11 @@ import java.io.IOException; import java.io.PrintWriter; import java.nio.channels.FileChannel; import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collections; import java.util.Date; -import java.util.List; -import java.util.Locale; public class Utils { - private static final String TAG = Utils.class.getSimpleName(); - private static final int MINIMUM_SAFETY_NET_CHAR_LENGTH = 4; - private static boolean DBG = LatinImeLogger.sDBG; - private static boolean DBG_EDIT_DISTANCE = false; - private Utils() { - // Intentional empty constructor for utility class. + // This utility class is not publicly instantiable. } /** @@ -118,166 +98,6 @@ public class Utils { } } - // TODO: Move InputMethodSubtype related utility methods to its own utility class. - // TODO: Cache my InputMethodInfo and/or InputMethodSubtype list. - public static boolean checkIfSubtypeBelongsToThisIme(Context context, - InputMethodSubtypeCompatWrapper ims) { - final InputMethodManagerCompatWrapper imm = InputMethodManagerCompatWrapper.getInstance(); - if (imm == null) return false; - - final InputMethodInfoCompatWrapper myImi = Utils.getInputMethodInfo( - context.getPackageName()); - final List<InputMethodSubtypeCompatWrapper> subtypes = - imm.getEnabledInputMethodSubtypeList(myImi, true); - for (final InputMethodSubtypeCompatWrapper subtype : subtypes) { - if (subtype.equals(ims)) { - return true; - } - } - return false; - } - - public static boolean hasMultipleEnabledIMEsOrSubtypes( - final boolean shouldIncludeAuxiliarySubtypes) { - final InputMethodManagerCompatWrapper imm = InputMethodManagerCompatWrapper.getInstance(); - if (imm == null) return false; - - final List<InputMethodInfoCompatWrapper> enabledImis = imm.getEnabledInputMethodList(); - return hasMultipleEnabledSubtypes(shouldIncludeAuxiliarySubtypes, enabledImis); - } - - public static boolean hasMultipleEnabledSubtypesInThisIme(Context context, - final boolean shouldIncludeAuxiliarySubtypes) { - final InputMethodInfoCompatWrapper myImi = Utils.getInputMethodInfo( - context.getPackageName()); - final List<InputMethodInfoCompatWrapper> imiList = Collections.singletonList(myImi); - return Utils.hasMultipleEnabledSubtypes(shouldIncludeAuxiliarySubtypes, imiList); - } - - private static boolean hasMultipleEnabledSubtypes(final boolean shouldIncludeAuxiliarySubtypes, - List<InputMethodInfoCompatWrapper> imiList) { - final InputMethodManagerCompatWrapper imm = InputMethodManagerCompatWrapper.getInstance(); - if (imm == null) return false; - - // Number of the filtered IMEs - int filteredImisCount = 0; - - for (InputMethodInfoCompatWrapper imi : imiList) { - // We can return true immediately after we find two or more filtered IMEs. - if (filteredImisCount > 1) return true; - final List<InputMethodSubtypeCompatWrapper> subtypes = - imm.getEnabledInputMethodSubtypeList(imi, true); - // IMEs that have no subtypes should be counted. - if (subtypes.isEmpty()) { - ++filteredImisCount; - continue; - } - - int auxCount = 0; - for (InputMethodSubtypeCompatWrapper subtype : subtypes) { - if (subtype.isAuxiliary()) { - ++auxCount; - } - } - final int nonAuxCount = subtypes.size() - auxCount; - - // IMEs that have one or more non-auxiliary subtypes should be counted. - // If shouldIncludeAuxiliarySubtypes is true, IMEs that have two or more auxiliary - // subtypes should be counted as well. - if (nonAuxCount > 0 || (shouldIncludeAuxiliarySubtypes && auxCount > 1)) { - ++filteredImisCount; - continue; - } - } - - if (filteredImisCount > 1) { - return true; - } - final List<InputMethodSubtypeCompatWrapper> subtypes = - imm.getEnabledInputMethodSubtypeList(null, true); - int keyboardCount = 0; - // imm.getEnabledInputMethodSubtypeList(null, true) will return the current IME's - // both explicitly and implicitly enabled input method subtype. - // (The current IME should be LatinIME.) - for (InputMethodSubtypeCompatWrapper subtype : subtypes) { - if (SubtypeSwitcher.KEYBOARD_MODE.equals(subtype.getMode())) { - ++keyboardCount; - } - } - return keyboardCount > 1; - } - - public static String getInputMethodId(String packageName) { - return getInputMethodInfo(packageName).getId(); - } - - public static InputMethodInfoCompatWrapper getInputMethodInfo(String packageName) { - final InputMethodManagerCompatWrapper imm = InputMethodManagerCompatWrapper.getInstance(); - if (imm == null) { - throw new RuntimeException("Input method manager not found"); - } - - for (final InputMethodInfoCompatWrapper imi : imm.getEnabledInputMethodList()) { - if (imi.getPackageName().equals(packageName)) - return imi; - } - throw new RuntimeException("Can not find input method id for " + packageName); - } - - // TODO: Resolve the inconsistencies between the native auto correction algorithms and - // this safety net - public static boolean shouldBlockAutoCorrectionBySafetyNet( - SuggestedWords.Builder suggestedWordsBuilder, Suggest suggest) { - // Safety net for auto correction. - // Actually if we hit this safety net, it's actually a bug. - if (suggestedWordsBuilder.size() <= 1 || suggestedWordsBuilder.isTypedWordValid()) { - return false; - } - // If user selected aggressive auto correction mode, there is no need to use the safety - // net. - if (suggest.isAggressiveAutoCorrectionMode()) { - return false; - } - final CharSequence typedWord = suggestedWordsBuilder.getWord(0); - // If the length of typed word is less than MINIMUM_SAFETY_NET_CHAR_LENGTH, - // we should not use net because relatively edit distance can be big. - if (typedWord.length() < MINIMUM_SAFETY_NET_CHAR_LENGTH) { - return false; - } - final CharSequence suggestionWord = suggestedWordsBuilder.getWord(1); - final int typedWordLength = typedWord.length(); - final int maxEditDistanceOfNativeDictionary = - (typedWordLength < 5 ? 2 : typedWordLength / 2) + 1; - final int distance = BinaryDictionary.editDistance( - typedWord.toString(), suggestionWord.toString()); - if (DBG) { - Log.d(TAG, "Autocorrected edit distance = " + distance - + ", " + maxEditDistanceOfNativeDictionary); - } - if (distance > maxEditDistanceOfNativeDictionary) { - if (DBG) { - Log.e(TAG, "Safety net: before = " + typedWord + ", after = " + suggestionWord); - Log.e(TAG, "(Error) The edit distance of this correction exceeds limit. " - + "Turning off auto-correction."); - } - return true; - } else { - return false; - } - } - - public static boolean canBeFollowedByPeriod(final int codePoint) { - // TODO: Check again whether there really ain't a better way to check this. - // TODO: This should probably be language-dependant... - return Character.isLetterOrDigit(codePoint) - || codePoint == Keyboard.CODE_SINGLE_QUOTE - || codePoint == Keyboard.CODE_DOUBLE_QUOTE - || codePoint == Keyboard.CODE_CLOSING_PARENTHESIS - || codePoint == Keyboard.CODE_CLOSING_SQUARE_BRACKET - || codePoint == Keyboard.CODE_CLOSING_CURLY_BRACKET - || codePoint == Keyboard.CODE_CLOSING_ANGLE_BRACKET; - } - /* package */ static class RingCharBuffer { private static RingCharBuffer sRingCharBuffer = new RingCharBuffer(); private static final char PLACEHOLDER_DELIMITER_CHAR = '\uFFFC'; @@ -600,147 +420,6 @@ public class Utils { } } - // TODO: Move this method to KeyboardSet class. - public static int getKeyboardMode(EditorInfo editorInfo) { - if (editorInfo == null) - return KeyboardId.MODE_TEXT; - - final int inputType = editorInfo.inputType; - final int variation = inputType & InputType.TYPE_MASK_VARIATION; - - switch (inputType & InputType.TYPE_MASK_CLASS) { - case InputType.TYPE_CLASS_NUMBER: - return KeyboardId.MODE_NUMBER; - case InputType.TYPE_CLASS_DATETIME: - switch (variation) { - case InputType.TYPE_DATETIME_VARIATION_DATE: - return KeyboardId.MODE_DATE; - case InputType.TYPE_DATETIME_VARIATION_TIME: - return KeyboardId.MODE_TIME; - default: // InputType.TYPE_DATETIME_VARIATION_NORMAL - return KeyboardId.MODE_DATETIME; - } - case InputType.TYPE_CLASS_PHONE: - return KeyboardId.MODE_PHONE; - case InputType.TYPE_CLASS_TEXT: - if (InputTypeCompatUtils.isEmailVariation(variation)) { - return KeyboardId.MODE_EMAIL; - } else if (variation == InputType.TYPE_TEXT_VARIATION_URI) { - return KeyboardId.MODE_URL; - } else if (variation == InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE) { - return KeyboardId.MODE_IM; - } else if (variation == InputType.TYPE_TEXT_VARIATION_FILTER) { - return KeyboardId.MODE_TEXT; - } else { - return KeyboardId.MODE_TEXT; - } - default: - return KeyboardId.MODE_TEXT; - } - } - - public static boolean containsInCsv(String key, String csv) { - if (csv == null) - return false; - for (String option : csv.split(",")) { - if (option.equals(key)) - return true; - } - return false; - } - - public static boolean inPrivateImeOptions(String packageName, String key, - EditorInfo editorInfo) { - if (editorInfo == null) - return false; - return containsInCsv(packageName != null ? packageName + "." + key : key, - editorInfo.privateImeOptions); - } - - /** - * Returns a main dictionary resource id - * @return main dictionary resource id - */ - public static int getMainDictionaryResourceId(Resources res) { - final String MAIN_DIC_NAME = "main"; - String packageName = LatinIME.class.getPackage().getName(); - return res.getIdentifier(MAIN_DIC_NAME, "raw", packageName); - } - - public static void loadNativeLibrary() { - try { - System.loadLibrary(JniLibName.JNI_LIB_NAME); - } catch (UnsatisfiedLinkError ule) { - Log.e(TAG, "Could not load native library " + JniLibName.JNI_LIB_NAME); - if (LatinImeLogger.sDBG) { - throw new RuntimeException( - "Could not load native library " + JniLibName.JNI_LIB_NAME); - } - } - } - - /** - * Returns true if a and b are equal ignoring the case of the character. - * @param a first character to check - * @param b second character to check - * @return {@code true} if a and b are equal, {@code false} otherwise. - */ - public static boolean equalsIgnoreCase(char a, char b) { - // Some language, such as Turkish, need testing both cases. - return a == b - || Character.toLowerCase(a) == Character.toLowerCase(b) - || Character.toUpperCase(a) == Character.toUpperCase(b); - } - - /** - * Returns true if a and b are equal ignoring the case of the characters, including if they are - * both null. - * @param a first CharSequence to check - * @param b second CharSequence to check - * @return {@code true} if a and b are equal, {@code false} otherwise. - */ - public static boolean equalsIgnoreCase(CharSequence a, CharSequence b) { - if (a == b) - return true; // including both a and b are null. - if (a == null || b == null) - return false; - final int length = a.length(); - if (length != b.length()) - return false; - for (int i = 0; i < length; i++) { - if (!equalsIgnoreCase(a.charAt(i), b.charAt(i))) - return false; - } - return true; - } - - /** - * Returns true if a and b are equal ignoring the case of the characters, including if a is null - * and b is zero length. - * @param a CharSequence to check - * @param b character array to check - * @param offset start offset of array b - * @param length length of characters in array b - * @return {@code true} if a and b are equal, {@code false} otherwise. - * @throws IndexOutOfBoundsException - * if {@code offset < 0 || length < 0 || offset + length > data.length}. - * @throws NullPointerException if {@code b == null}. - */ - public static boolean equalsIgnoreCase(CharSequence a, char[] b, int offset, int length) { - if (offset < 0 || length < 0 || length > b.length - offset) - throw new IndexOutOfBoundsException("array.length=" + b.length + " offset=" + offset - + " length=" + length); - if (a == null) - return length == 0; // including a is null and b is zero length. - if (a.length() != length) - return false; - for (int i = 0; i < length; i++) { - if (!equalsIgnoreCase(a.charAt(i), b[offset + i])) - return false; - } - return true; - } - public static float getDipScale(Context context) { final float scale = context.getResources().getDisplayMetrics().density; return scale; @@ -751,76 +430,6 @@ public class Utils { return (int) (dip * scale + 0.5); } - /** - * Remove duplicates from an array of strings. - * - * This method will always keep the first occurence of all strings at their position - * in the array, removing the subsequent ones. - */ - public static void removeDupes(final ArrayList<CharSequence> suggestions) { - if (suggestions.size() < 2) return; - int i = 1; - // Don't cache suggestions.size(), since we may be removing items - while (i < suggestions.size()) { - final CharSequence cur = suggestions.get(i); - // Compare each suggestion with each previous suggestion - for (int j = 0; j < i; j++) { - CharSequence previous = suggestions.get(j); - if (TextUtils.equals(cur, previous)) { - removeFromSuggestions(suggestions, i); - i--; - break; - } - } - i++; - } - } - - private static void removeFromSuggestions(final ArrayList<CharSequence> suggestions, - final int index) { - final CharSequence garbage = suggestions.remove(index); - if (garbage instanceof StringBuilder) { - StringBuilderPool.recycle((StringBuilder)garbage); - } - } - - public static String getFullDisplayName(Locale locale, boolean returnsNameInThisLocale) { - if (returnsNameInThisLocale) { - return toTitleCase(SubtypeLocale.getFullDisplayName(locale), locale); - } else { - return toTitleCase(locale.getDisplayName(), locale); - } - } - - public static String getDisplayLanguage(Locale locale) { - return toTitleCase(SubtypeLocale.getFullDisplayName(locale), locale); - } - - public static String getMiddleDisplayLanguage(Locale locale) { - return toTitleCase((LocaleUtils.constructLocaleFromString( - locale.getLanguage()).getDisplayLanguage(locale)), locale); - } - - public static String getShortDisplayLanguage(Locale locale) { - return toTitleCase(locale.getLanguage(), locale); - } - - public static String toTitleCase(String s, Locale locale) { - if (s.length() <= 1) { - // TODO: is this really correct? Shouldn't this be s.toUpperCase()? - return s; - } - // TODO: fix the bugs below - // - This does not work for Greek, because it returns upper case instead of title case. - // - It does not work for Serbian, because it fails to account for the "lj" character, - // which should be "Lj" in title case and "LJ" in upper case. - // - It does not work for Dutch, because it fails to account for the "ij" digraph, which - // are two different characters but both should be capitalized as "IJ" as if they were - // a single letter. - // - It also does not work with unicode surrogate code points. - return s.toUpperCase(locale).charAt(0) + s.substring(1); - } - public static class Stats { public static void onNonSeparator(final char code, final int x, final int y) { @@ -845,9 +454,4 @@ public class Utils { LatinImeLogger.logOnAutoCorrectionCancelled(); } } - - public static int codePointCount(String text) { - if (TextUtils.isEmpty(text)) return 0; - return text.codePointCount(0, text.length()); - } } |