diff options
Diffstat (limited to 'java/src/com/android/inputmethod/latin')
20 files changed, 189 insertions, 414 deletions
diff --git a/java/src/com/android/inputmethod/latin/AutoCorrection.java b/java/src/com/android/inputmethod/latin/AutoCorrection.java index 9c35f8f6f..ef88f9906 100644 --- a/java/src/com/android/inputmethod/latin/AutoCorrection.java +++ b/java/src/com/android/inputmethod/latin/AutoCorrection.java @@ -20,7 +20,7 @@ import android.text.TextUtils; import android.util.Log; import java.util.ArrayList; -import java.util.Map; +import java.util.HashMap; public class AutoCorrection { private static final boolean DBG = LatinImeLogger.sDBG; @@ -30,7 +30,7 @@ public class AutoCorrection { // Purely static class: can't instantiate. } - public static CharSequence computeAutoCorrectionWord(Map<String, Dictionary> dictionaries, + public static CharSequence computeAutoCorrectionWord(HashMap<String, Dictionary> dictionaries, WordComposer wordComposer, ArrayList<CharSequence> suggestions, int[] sortedScores, CharSequence consideredWord, double autoCorrectionThreshold, CharSequence whitelistedWord) { @@ -47,7 +47,7 @@ public class AutoCorrection { } public static boolean isValidWord( - Map<String, Dictionary> dictionaries, CharSequence word, boolean ignoreCase) { + HashMap<String, Dictionary> dictionaries, CharSequence word, boolean ignoreCase) { if (TextUtils.isEmpty(word)) { return false; } @@ -72,7 +72,7 @@ public class AutoCorrection { } public static boolean allowsToBeAutoCorrected( - Map<String, Dictionary> dictionaries, CharSequence word, boolean ignoreCase) { + HashMap<String, Dictionary> dictionaries, CharSequence word, boolean ignoreCase) { final WhitelistDictionary whitelistDictionary = (WhitelistDictionary)dictionaries.get(Suggest.DICT_KEY_WHITELIST); // If "word" is in the whitelist dictionary, it should not be auto corrected. @@ -87,9 +87,9 @@ public class AutoCorrection { return whiteListedWord != null; } - private static boolean hasAutoCorrectionForConsideredWord(Map<String, Dictionary> dictionaries, - WordComposer wordComposer, ArrayList<CharSequence> suggestions, - CharSequence consideredWord) { + private static boolean hasAutoCorrectionForConsideredWord( + HashMap<String, Dictionary> dictionaries, WordComposer wordComposer, + ArrayList<CharSequence> suggestions, CharSequence consideredWord) { if (TextUtils.isEmpty(consideredWord)) return false; return wordComposer.size() > 1 && suggestions.size() > 0 && !allowsToBeAutoCorrected(dictionaries, consideredWord, false); diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java index 31ff4e7b4..dfc8c8e9d 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java @@ -149,6 +149,9 @@ public class BinaryDictionary extends Dictionary { int count = getBigramsNative(mNativeDict, chars, chars.length, mInputCodes, codesSize, mOutputChars_bigrams, mBigramScores, MAX_WORD_LENGTH, MAX_BIGRAMS, MAX_PROXIMITY_CHARS_SIZE); + if (count > MAX_BIGRAMS) { + count = MAX_BIGRAMS; + } for (int j = 0; j < count; ++j) { if (codesSize > 0 && mBigramScores[j] < 1) break; diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java index 9ffc7d0a2..8ec440500 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryFileDumper.java @@ -196,8 +196,8 @@ public class BinaryDictionaryFileDumper { } finally { // Ignore exceptions while closing files. try { - // afd.close() will close inputStream, we should not call inputStream.close(). - if (null != afd) afd.close(); + // inputStream.close() will close afd, we should not call afd.close(). + if (null != inputStream) inputStream.close(); } catch (Exception e) { Log.e(TAG, "Exception while closing a cross-process file descriptor : " + e); } diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java index 79441c557..1c24cd11d 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionaryGetter.java @@ -25,7 +25,6 @@ import android.util.Log; import java.io.File; import java.util.ArrayList; -import java.util.List; import java.util.Locale; /** @@ -264,9 +263,9 @@ class BinaryDictionaryGetter { * - Gets a file name from the fallback resource passed as an argument. * If that fails: * - Returns null. - * @return The address of a valid file, or null. + * @return The list of addresses of valid dictionary files, or null. */ - public static List<AssetFileAddress> getDictionaryFiles(final Locale locale, + public static ArrayList<AssetFileAddress> getDictionaryFiles(final Locale locale, final Context context, final int fallbackResId) { // cacheWordListsFromContentProvider returns the list of files it copied to local diff --git a/java/src/com/android/inputmethod/latin/DebugSettings.java b/java/src/com/android/inputmethod/latin/DebugSettings.java index 870b33f9a..23d63b42a 100644 --- a/java/src/com/android/inputmethod/latin/DebugSettings.java +++ b/java/src/com/android/inputmethod/latin/DebugSettings.java @@ -30,7 +30,7 @@ import com.android.inputmethod.keyboard.KeyboardSwitcher; public class DebugSettings extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener { - private static final String TAG = "DebugSettings"; + private static final String TAG = DebugSettings.class.getSimpleName(); private static final String DEBUG_MODE_KEY = "debug_mode"; public static final String FORCE_NON_DISTINCT_MULTITOUCH_KEY = "force_non_distinct_multitouch"; diff --git a/java/src/com/android/inputmethod/latin/DictionaryCollection.java b/java/src/com/android/inputmethod/latin/DictionaryCollection.java index c19a5a718..5de770a4a 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryCollection.java +++ b/java/src/com/android/inputmethod/latin/DictionaryCollection.java @@ -22,7 +22,6 @@ import android.util.Log; import java.util.Collection; import java.util.Collections; -import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; /** @@ -30,7 +29,7 @@ import java.util.concurrent.CopyOnWriteArrayList; */ public class DictionaryCollection extends Dictionary { private final String TAG = DictionaryCollection.class.getSimpleName(); - protected final List<Dictionary> mDictionaries; + protected final CopyOnWriteArrayList<Dictionary> mDictionaries; public DictionaryCollection() { mDictionaries = new CopyOnWriteArrayList<Dictionary>(); diff --git a/java/src/com/android/inputmethod/latin/DictionaryFactory.java b/java/src/com/android/inputmethod/latin/DictionaryFactory.java index 7a81f7bd5..77c685c50 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFactory.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java @@ -22,8 +22,8 @@ import android.content.res.Resources; import android.util.Log; import java.io.File; +import java.util.ArrayList; import java.util.LinkedList; -import java.util.List; import java.util.Locale; /** @@ -52,8 +52,8 @@ public class DictionaryFactory { return new DictionaryCollection(createBinaryDictionary(context, fallbackResId, locale)); } - final List<Dictionary> dictList = new LinkedList<Dictionary>(); - final List<AssetFileAddress> assetFileList = + final LinkedList<Dictionary> dictList = new LinkedList<Dictionary>(); + final ArrayList<AssetFileAddress> assetFileList = BinaryDictionaryGetter.getDictionaryFiles(locale, context, fallbackResId); if (null != assetFileList) { for (final AssetFileAddress f : assetFileList) { diff --git a/java/src/com/android/inputmethod/latin/InputAttributes.java b/java/src/com/android/inputmethod/latin/InputAttributes.java index f7afed2a5..06c70c42c 100644 --- a/java/src/com/android/inputmethod/latin/InputAttributes.java +++ b/java/src/com/android/inputmethod/latin/InputAttributes.java @@ -95,6 +95,7 @@ public class InputAttributes { } } + @SuppressWarnings("unused") private void dumpFlags(final int inputType) { Log.i(TAG, "Input class:"); final int inputClass = inputType & InputType.TYPE_MASK_CLASS; diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 7c08377be..e67f0ea05 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -73,7 +73,6 @@ import com.android.inputmethod.latin.suggestions.SuggestionsView; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.List; import java.util.Locale; /** @@ -203,8 +202,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar private boolean mShouldSwitchToLastSubtype = true; private UserDictionary mUserDictionary; - private UserBigramDictionary mUserBigramDictionary; - private UserUnigramDictionary mUserUnigramDictionary; + private UserHistoryDictionary mUserHistoryDictionary; private boolean mIsUserDictionaryAvailable; private LastComposedWord mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD; @@ -528,13 +526,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar resetContactsDictionary(oldContactsDictionary); - mUserUnigramDictionary - = new UserUnigramDictionary(this, this, localeStr, Suggest.DIC_USER_UNIGRAM); - mSuggest.setUserUnigramDictionary(mUserUnigramDictionary); - - mUserBigramDictionary - = new UserBigramDictionary(this, this, localeStr, Suggest.DIC_USER_BIGRAM); - mSuggest.setUserBigramDictionary(mUserBigramDictionary); + mUserHistoryDictionary + = new UserHistoryDictionary(this, this, localeStr, Suggest.DIC_USER_HISTORY); + mSuggest.setUserHistoryDictionary(mUserHistoryDictionary); LocaleUtils.setSystemLocale(res, savedLocale); } @@ -776,8 +770,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar KeyboardView inputView = mKeyboardSwitcher.getKeyboardView(); if (inputView != null) inputView.closing(); - if (mUserUnigramDictionary != null) mUserUnigramDictionary.flushPendingWrites(); - if (mUserBigramDictionary != null) mUserBigramDictionary.flushPendingWrites(); + if (mUserHistoryDictionary != null) mUserHistoryDictionary.flushPendingWrites(); } private void onFinishInputViewInternal(boolean finishingInput) { @@ -923,7 +916,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar return; } - final List<SuggestedWords.SuggestedWordInfo> applicationSuggestedWords = + final ArrayList<SuggestedWords.SuggestedWordInfo> applicationSuggestedWords = SuggestedWords.getFromApplicationSpecifiedCompletions( applicationSpecifiedCompletions); final SuggestedWords suggestedWords = new SuggestedWords( @@ -1295,7 +1288,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar mDeleteCount++; mExpectingUpdateSelection = true; mShouldSwitchToLastSubtype = true; - LatinImeLogger.logOnDelete(); + LatinImeLogger.logOnDelete(x, y); break; case Keyboard.CODE_SHIFT: case Keyboard.CODE_SWITCH_ALPHA_SYMBOL: @@ -1995,9 +1988,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar setSuggestionStripShown(isSuggestionsStripVisible()); } - /** - * Adds to the UserBigramDictionary and/or UserUnigramDictionary - */ private void addToUserHistoryDictionary(final CharSequence suggestion) { if (suggestion == null || suggestion.length() < 1) return; @@ -2009,19 +1999,16 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar return; } - if (null != mUserUnigramDictionary) { - mUserUnigramDictionary.addUnigram(suggestion.toString()); - } - - if (mUserBigramDictionary != null) { + if (mUserHistoryDictionary != null) { final InputConnection ic = getCurrentInputConnection(); + final CharSequence prevWord; if (null != ic) { - final CharSequence prevWord = - EditingUtils.getPreviousWord(ic, mSettingsValues.mWordSeparators); - if (null != prevWord) { - mUserBigramDictionary.addBigramPair(prevWord.toString(), suggestion.toString()); - } + prevWord = EditingUtils.getPreviousWord(ic, mSettingsValues.mWordSeparators); + } else { + prevWord = null; } + mUserHistoryDictionary.addToUserHistory(null == prevWord ? null : prevWord.toString(), + suggestion.toString()); } } diff --git a/java/src/com/android/inputmethod/latin/LatinImeLogger.java b/java/src/com/android/inputmethod/latin/LatinImeLogger.java index 5390ee39e..079f3b5dd 100644 --- a/java/src/com/android/inputmethod/latin/LatinImeLogger.java +++ b/java/src/com/android/inputmethod/latin/LatinImeLogger.java @@ -22,8 +22,6 @@ import android.view.inputmethod.EditorInfo; import com.android.inputmethod.keyboard.Keyboard; -import java.util.List; - public class LatinImeLogger implements SharedPreferences.OnSharedPreferenceChangeListener { public static boolean sDBG = false; @@ -53,7 +51,7 @@ public class LatinImeLogger implements SharedPreferences.OnSharedPreferenceChang public static void logOnAutoCorrectionCancelled() { } - public static void logOnDelete() { + public static void logOnDelete(int x, int y) { } public static void logOnInputChar() { diff --git a/java/src/com/android/inputmethod/latin/SettingsValues.java b/java/src/com/android/inputmethod/latin/SettingsValues.java index 4346a3671..c1335fdfe 100644 --- a/java/src/com/android/inputmethod/latin/SettingsValues.java +++ b/java/src/com/android/inputmethod/latin/SettingsValues.java @@ -19,19 +19,15 @@ package com.android.inputmethod.latin; import android.content.Context; import android.content.SharedPreferences; import android.content.res.Resources; -import android.os.Build; import android.util.Log; import android.view.inputmethod.EditorInfo; -import com.android.inputmethod.compat.InputMethodInfoCompatWrapper; import com.android.inputmethod.compat.InputTypeCompatUtils; import com.android.inputmethod.compat.VibratorCompatWrapper; import com.android.inputmethod.keyboard.internal.KeySpecParser; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; -import java.util.List; import java.util.Locale; public class SettingsValues { @@ -325,14 +321,8 @@ public class SettingsValues { return volume; } - final String[] volumePerHardwareList = res.getStringArray(R.array.keypress_volumes); - final String hardwarePrefix = Build.HARDWARE + ","; - for (final String element : volumePerHardwareList) { - if (element.startsWith(hardwarePrefix)) { - return Float.parseFloat(element.substring(element.lastIndexOf(',') + 1)); - } - } - return -1.0f; + return Float.parseFloat( + Utils.getDeviceOverrideValue(res, R.array.keypress_volumes, "-1.0f")); } // Likewise @@ -343,15 +333,9 @@ public class SettingsValues { if (ms >= 0) { return ms; } - final String[] durationPerHardwareList = res.getStringArray( - R.array.keypress_vibration_durations); - final String hardwarePrefix = Build.HARDWARE + ","; - for (final String element : durationPerHardwareList) { - if (element.startsWith(hardwarePrefix)) { - return (int)Long.parseLong(element.substring(element.lastIndexOf(',') + 1)); - } - } - return -1; + + return Integer.parseInt( + Utils.getDeviceOverrideValue(res, R.array.keypress_vibration_durations, "-1")); } // Likewise diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java index 69754d769..9ae2506f4 100644 --- a/java/src/com/android/inputmethod/latin/Suggest.java +++ b/java/src/com/android/inputmethod/latin/Suggest.java @@ -30,15 +30,12 @@ import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Locale; -import java.util.Map; -import java.util.Set; /** * This class loads a dictionary and provides a list of suggestions for a given sequence of * characters. This includes corrections and completions. */ public class Suggest implements Dictionary.WordCallback { - public static final String TAG = Suggest.class.getSimpleName(); public static final int APPROX_MAX_WORD_LENGTH = 32; @@ -65,9 +62,8 @@ public class Suggest implements Dictionary.WordCallback { public static final int DIC_USER_TYPED = 0; public static final int DIC_MAIN = 1; public static final int DIC_USER = 2; - public static final int DIC_USER_UNIGRAM = 3; + public static final int DIC_USER_HISTORY = 3; public static final int DIC_CONTACTS = 4; - public static final int DIC_USER_BIGRAM = 5; public static final int DIC_WHITELIST = 6; // If you add a type of dictionary, increment DIC_TYPE_LAST_ID // TODO: this value seems unused. Remove it? @@ -76,10 +72,10 @@ public class Suggest implements Dictionary.WordCallback { public static final String DICT_KEY_CONTACTS = "contacts"; // User dictionary, the system-managed one. public static final String DICT_KEY_USER = "user"; - // User unigram dictionary, internal to LatinIME - public static final String DICT_KEY_USER_UNIGRAM = "user_unigram"; - // User bigram dictionary, internal to LatinIME - public static final String DICT_KEY_USER_BIGRAM = "user_bigram"; + // User history dictionary for the unigram map, internal to LatinIME + public static final String DICT_KEY_USER_HISTORY_UNIGRAM = "history_unigram"; + // User history dictionary for the bigram map, internal to LatinIME + public static final String DICT_KEY_USER_HISTORY_BIGRAM = "history_bigram"; public static final String DICT_KEY_WHITELIST ="whitelist"; private static final boolean DBG = LatinImeLogger.sDBG; @@ -87,8 +83,10 @@ public class Suggest implements Dictionary.WordCallback { private Dictionary mMainDict; private ContactsDictionary mContactsDict; private WhitelistDictionary mWhiteListDictionary; - private final Map<String, Dictionary> mUnigramDictionaries = new HashMap<String, Dictionary>(); - private final Map<String, Dictionary> mBigramDictionaries = new HashMap<String, Dictionary>(); + private final HashMap<String, Dictionary> mUnigramDictionaries = + new HashMap<String, Dictionary>(); + private final HashMap<String, Dictionary> mBigramDictionaries = + new HashMap<String, Dictionary>(); private int mPrefMaxSuggestions = 18; @@ -142,7 +140,7 @@ public class Suggest implements Dictionary.WordCallback { initWhitelistAndAutocorrectAndPool(context, locale); } - private static void addOrReplaceDictionary(Map<String, Dictionary> dictionaries, String key, + private static void addOrReplaceDictionary(HashMap<String, Dictionary> dictionaries, String key, Dictionary dict) { final Dictionary oldDict = (dict == null) ? dictionaries.remove(key) @@ -177,7 +175,7 @@ public class Suggest implements Dictionary.WordCallback { return mContactsDict; } - public Map<String, Dictionary> getUnigramDictionaries() { + public HashMap<String, Dictionary> getUnigramDictionaries() { return mUnigramDictionaries; } @@ -204,12 +202,11 @@ public class Suggest implements Dictionary.WordCallback { addOrReplaceDictionary(mBigramDictionaries, DICT_KEY_CONTACTS, contactsDictionary); } - public void setUserUnigramDictionary(Dictionary userUnigramDictionary) { - addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_USER_UNIGRAM, userUnigramDictionary); - } - - public void setUserBigramDictionary(Dictionary userBigramDictionary) { - addOrReplaceDictionary(mBigramDictionaries, DICT_KEY_USER_BIGRAM, userBigramDictionary); + public void setUserHistoryDictionary(Dictionary userHistoryDictionary) { + addOrReplaceDictionary(mUnigramDictionaries, DICT_KEY_USER_HISTORY_UNIGRAM, + userHistoryDictionary); + addOrReplaceDictionary(mBigramDictionaries, DICT_KEY_USER_HISTORY_BIGRAM, + userHistoryDictionary); } public void setAutoCorrectionThreshold(double threshold) { @@ -348,7 +345,7 @@ public class Suggest implements Dictionary.WordCallback { // At second character typed, search the unigrams (scores being affected by bigrams) for (final String key : mUnigramDictionaries.keySet()) { // Skip UserUnigramDictionary and WhitelistDictionary to lookup - if (key.equals(DICT_KEY_USER_UNIGRAM) || key.equals(DICT_KEY_WHITELIST)) + if (key.equals(DICT_KEY_USER_HISTORY_UNIGRAM) || key.equals(DICT_KEY_WHITELIST)) continue; final Dictionary dictionary = mUnigramDictionaries.get(key); dictionary.getWords(wordComposerForLookup, this, proximityInfo); @@ -563,7 +560,7 @@ public class Suggest implements Dictionary.WordCallback { } public void close() { - final Set<Dictionary> dictionaries = new HashSet<Dictionary>(); + final HashSet<Dictionary> dictionaries = new HashSet<Dictionary>(); dictionaries.addAll(mUnigramDictionaries.values()); dictionaries.addAll(mBigramDictionaries.values()); for (final Dictionary dictionary : dictionaries) { diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java index b63bc6c29..ef8e58e0c 100644 --- a/java/src/com/android/inputmethod/latin/SuggestedWords.java +++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java @@ -21,22 +21,20 @@ import android.view.inputmethod.CompletionInfo; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.HashSet; -import java.util.List; public class SuggestedWords { public static final SuggestedWords EMPTY = new SuggestedWords( - Collections.<SuggestedWordInfo>emptyList(), false, false, false, false, false); + new ArrayList<SuggestedWordInfo>(0), false, false, false, false, false); public final boolean mTypedWordValid; public final boolean mHasAutoCorrectionCandidate; public final boolean mIsPunctuationSuggestions; public final boolean mAllowsToBeAutoCorrected; public final boolean mIsObsoleteSuggestions; - private final List<SuggestedWordInfo> mSuggestedWordInfoList; + private final ArrayList<SuggestedWordInfo> mSuggestedWordInfoList; - public SuggestedWords(final List<SuggestedWordInfo> suggestedWordInfoList, + public SuggestedWords(final ArrayList<SuggestedWordInfo> suggestedWordInfoList, final boolean typedWordValid, final boolean hasAutoCorrectionCandidate, final boolean allowsToBeAutoCorrected, @@ -82,7 +80,7 @@ public class SuggestedWords { } public static ArrayList<SuggestedWordInfo> getFromCharSequenceList( - final List<CharSequence> wordList) { + final ArrayList<CharSequence> wordList) { final ArrayList<SuggestedWordInfo> result = new ArrayList<SuggestedWordInfo>(); for (CharSequence word : wordList) { if (null != word) result.add(new SuggestedWordInfo(word)); @@ -90,7 +88,7 @@ public class SuggestedWords { return result; } - public static List<SuggestedWordInfo> getFromApplicationSpecifiedCompletions( + public static ArrayList<SuggestedWordInfo> getFromApplicationSpecifiedCompletions( final CompletionInfo[] infos) { final ArrayList<SuggestedWordInfo> result = new ArrayList<SuggestedWordInfo>(); for (CompletionInfo info : infos) { diff --git a/java/src/com/android/inputmethod/latin/UserBigramDictionary.java b/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java index 52a31f2e6..4e798460c 100644 --- a/java/src/com/android/inputmethod/latin/UserBigramDictionary.java +++ b/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java @@ -31,12 +31,11 @@ import java.util.HashSet; import java.util.Iterator; /** - * Stores all the pairs user types in databases. Prune the database if the size - * gets too big. Unlike AutoDictionary, it even stores the pairs that are already - * in the dictionary. + * Locally gathers stats about the words user types and various other signals like auto-correction + * cancellation or manual picks. This allows the keyboard to adapt to the typist over time. */ -public class UserBigramDictionary extends ExpandableDictionary { - private static final String TAG = "UserBigramDictionary"; +public class UserHistoryDictionary extends ExpandableDictionary { + private static final String TAG = "UserHistoryDictionary"; /** Any pair being typed or picked */ private static final int FREQUENCY_FOR_TYPED = 2; @@ -45,14 +44,14 @@ public class UserBigramDictionary extends ExpandableDictionary { private static final int FREQUENCY_MAX = 127; /** Maximum number of pairs. Pruning will start when databases goes above this number. */ - private static int sMaxUserBigrams = 10000; + private static int sMaxHistoryBigrams = 10000; /** * When it hits maximum bigram pair, it will delete until you are left with - * only (sMaxUserBigrams - sDeleteUserBigrams) pairs. + * only (sMaxHistoryBigrams - sDeleteHistoryBigrams) pairs. * Do not keep this number small to avoid deleting too often. */ - private static int sDeleteUserBigrams = 1000; + private static int sDeleteHistoryBigrams = 1000; /** * Database version should increase if the database structure changes @@ -64,7 +63,7 @@ public class UserBigramDictionary extends ExpandableDictionary { /** Name of the words table in the database */ private static final String MAIN_TABLE_NAME = "main"; // TODO: Consume less space by using a unique id for locale instead of the whole - // 2-5 character string. (Same TODO from AutoDictionary) + // 2-5 character string. private static final String MAIN_COLUMN_ID = BaseColumns._ID; private static final String MAIN_COLUMN_WORD1 = "word1"; private static final String MAIN_COLUMN_WORD2 = "word2"; @@ -114,8 +113,16 @@ public class UserBigramDictionary extends ExpandableDictionary { @Override public boolean equals(Object bigram) { - Bigram bigram2 = (Bigram) bigram; - return (mWord1.equals(bigram2.mWord1) && mWord2.equals(bigram2.mWord2)); + if (!(bigram instanceof Bigram)) { + return false; + } + final Bigram bigram2 = (Bigram) bigram; + final boolean eq1 = + mWord1 == null ? bigram2.mWord1 == null : mWord1.equals(bigram2.mWord1); + if (!eq1) { + return false; + } + return mWord2 == null ? bigram2.mWord2 == null : mWord2.equals(bigram2.mWord2); } @Override @@ -124,15 +131,15 @@ public class UserBigramDictionary extends ExpandableDictionary { } } - public void setDatabaseMax(int maxUserBigram) { - sMaxUserBigrams = maxUserBigram; + public void setDatabaseMax(int maxHistoryBigram) { + sMaxHistoryBigrams = maxHistoryBigram; } - public void setDatabaseDelete(int deleteUserBigram) { - sDeleteUserBigrams = deleteUserBigram; + public void setDatabaseDelete(int deleteHistoryBigram) { + sDeleteHistoryBigrams = deleteHistoryBigram; } - public UserBigramDictionary(Context context, LatinIME ime, String locale, int dicTypeId) { + public UserHistoryDictionary(Context context, LatinIME ime, String locale, int dicTypeId) { super(context, dicTypeId); mIme = ime; mLocale = locale; @@ -155,19 +162,39 @@ public class UserBigramDictionary extends ExpandableDictionary { } /** - * Pair will be added to the userbigram database. + * Return whether the passed charsequence is in the dictionary. + */ + @Override + public boolean isValidWord(final CharSequence word) { + // TODO: figure out what is the correct thing to do here. + return false; + } + + /** + * Pair will be added to the user history dictionary. + * + * The first word may be null. That means we don't know the context, in other words, + * it's only a unigram. The first word may also be an empty string : this means start + * context, as in beginning of a sentence for example. + * The second word may not be null (a NullPointerException would be thrown). */ - public int addBigramPair(String word1, String word2) { + public int addToUserHistory(final String word1, String word2) { // remove caps if second word is autocapitalized if (mIme != null && mIme.isAutoCapitalized()) { word2 = Character.toLowerCase(word2.charAt(0)) + word2.substring(1); } + super.addWord(word2, FREQUENCY_FOR_TYPED); // Do not insert a word as a bigram of itself - if (word1.equals(word2)) { + if (word2.equals(word1)) { return 0; } - int freq = super.addBigram(word1, word2, FREQUENCY_FOR_TYPED); + int freq; + if (null == word1) { + freq = FREQUENCY_FOR_TYPED; + } else { + freq = super.addBigram(word1, word2, FREQUENCY_FOR_TYPED); + } if (freq > FREQUENCY_MAX) freq = FREQUENCY_MAX; synchronized (mPendingWritesLock) { if (freq == FREQUENCY_FOR_TYPED || mPendingWrites.isEmpty()) { @@ -225,7 +252,10 @@ public class UserBigramDictionary extends ExpandableDictionary { int frequency = cursor.getInt(frequencyIndex); // Safeguard against adding really long words. Stack may overflow due // to recursive lookup - if (word1.length() < MAX_WORD_LENGTH && word2.length() < MAX_WORD_LENGTH) { + if (null == word1) { + super.addWord(word2, frequency); + } else if (word1.length() < MAX_WORD_LENGTH + && word2.length() < MAX_WORD_LENGTH) { super.setBigram(word1, word2, frequency); } cursor.moveToNext(); @@ -324,8 +354,8 @@ public class UserBigramDictionary extends ExpandableDictionary { try { int totalRowCount = c.getCount(); // prune out old data if we have too much data - if (totalRowCount > sMaxUserBigrams) { - int numDeleteRows = (totalRowCount - sMaxUserBigrams) + sDeleteUserBigrams; + if (totalRowCount > sMaxHistoryBigrams) { + int numDeleteRows = (totalRowCount - sMaxHistoryBigrams) + sDeleteHistoryBigrams; int pairIdColumnId = c.getColumnIndex(FREQ_COLUMN_PAIR_ID); c.moveToFirst(); int count = 0; @@ -367,13 +397,23 @@ public class UserBigramDictionary extends ExpandableDictionary { // Write all the entries to the db Iterator<Bigram> iterator = mMap.iterator(); while (iterator.hasNext()) { + // TODO: this process of making a text search for each pair each time + // is terribly inefficient. Optimize this. Bigram bi = iterator.next(); // find pair id - Cursor c = db.query(MAIN_TABLE_NAME, new String[] { MAIN_COLUMN_ID }, - MAIN_COLUMN_WORD1 + "=? AND " + MAIN_COLUMN_WORD2 + "=? AND " - + MAIN_COLUMN_LOCALE + "=?", - new String[] { bi.mWord1, bi.mWord2, mLocale }, null, null, null); + final Cursor c; + if (null != bi.mWord1) { + c = db.query(MAIN_TABLE_NAME, new String[] { MAIN_COLUMN_ID }, + MAIN_COLUMN_WORD1 + "=? AND " + MAIN_COLUMN_WORD2 + "=? AND " + + MAIN_COLUMN_LOCALE + "=?", + new String[] { bi.mWord1, bi.mWord2, mLocale }, null, null, null); + } else { + c = db.query(MAIN_TABLE_NAME, new String[] { MAIN_COLUMN_ID }, + MAIN_COLUMN_WORD1 + " IS NULL AND " + MAIN_COLUMN_WORD2 + "=? AND " + + MAIN_COLUMN_LOCALE + "=?", + new String[] { bi.mWord2, mLocale }, null, null, null); + } int pairId; if (c.moveToFirst()) { diff --git a/java/src/com/android/inputmethod/latin/UserUnigramDictionary.java b/java/src/com/android/inputmethod/latin/UserUnigramDictionary.java deleted file mode 100644 index 2fc395c3e..000000000 --- a/java/src/com/android/inputmethod/latin/UserUnigramDictionary.java +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -package com.android.inputmethod.latin; - -import android.content.ContentValues; -import android.content.Context; -import android.database.Cursor; -import android.database.sqlite.SQLiteDatabase; -import android.database.sqlite.SQLiteOpenHelper; -import android.database.sqlite.SQLiteQueryBuilder; -import android.os.AsyncTask; -import android.provider.BaseColumns; -import android.util.Log; - -import java.util.HashMap; -import java.util.Map.Entry; -import java.util.Set; - -/** - * This class (inherited from the old AutoDictionary) is used for user history - * based dictionary. It stores words that the user typed to supply a provision - * for suggesting and re-ordering of candidates. - */ -public class UserUnigramDictionary extends ExpandableDictionary { - static final boolean ENABLE_USER_UNIGRAM_DICTIONARY = false; - - // Weight added to a user picking a new word from the suggestion strip - static final int FREQUENCY_FOR_PICKED = 3; - // Weight added to a user typing a new word that doesn't get corrected (or is reverted) - static final int FREQUENCY_FOR_TYPED = 1; - // If the user touches a typed word 2 times or more, it will become valid. - private static final int VALIDITY_THRESHOLD = 2 * FREQUENCY_FOR_PICKED; - - private LatinIME mIme; - // Locale for which this user unigram dictionary is storing words - private String mLocale; - - private HashMap<String,Integer> mPendingWrites = new HashMap<String,Integer>(); - private final Object mPendingWritesLock = new Object(); - - // TODO: we should probably change the database name - private static final String DATABASE_NAME = "auto_dict.db"; - private static final int DATABASE_VERSION = 1; - - // These are the columns in the dictionary - // TODO: Consume less space by using a unique id for locale instead of the whole - // 2-5 character string. - private static final String COLUMN_ID = BaseColumns._ID; - private static final String COLUMN_WORD = "word"; - private static final String COLUMN_FREQUENCY = "freq"; - private static final String COLUMN_LOCALE = "locale"; - - /** Sort by descending order of frequency. */ - public static final String DEFAULT_SORT_ORDER = COLUMN_FREQUENCY + " DESC"; - - /** Name of the words table in the database */ - private static final String USER_UNIGRAM_DICT_TABLE_NAME = "words"; - - private static HashMap<String, String> sDictProjectionMap; - - static { - if (ENABLE_USER_UNIGRAM_DICTIONARY) { - sDictProjectionMap = new HashMap<String, String>(); - sDictProjectionMap.put(COLUMN_ID, COLUMN_ID); - sDictProjectionMap.put(COLUMN_WORD, COLUMN_WORD); - sDictProjectionMap.put(COLUMN_FREQUENCY, COLUMN_FREQUENCY); - sDictProjectionMap.put(COLUMN_LOCALE, COLUMN_LOCALE); - } - } - - private static DatabaseHelper sOpenHelper = null; - - public UserUnigramDictionary(Context context, LatinIME ime, String locale, int dicTypeId) { - super(context, dicTypeId); - // Super must be first statement of the constructor... I'd like not to do it if the - // user unigram dictionary is not enabled, but Java won't let me. - if (!ENABLE_USER_UNIGRAM_DICTIONARY) return; - mIme = ime; - mLocale = locale; - if (sOpenHelper == null) { - sOpenHelper = new DatabaseHelper(getContext()); - } - if (mLocale != null && mLocale.length() > 1) { - loadDictionary(); - } - } - - @Override - public synchronized boolean isValidWord(CharSequence word) { - if (!ENABLE_USER_UNIGRAM_DICTIONARY) return false; - final int frequency = getWordFrequency(word); - return frequency >= VALIDITY_THRESHOLD; - } - - @Override - public void close() { - super.close(); - if (!ENABLE_USER_UNIGRAM_DICTIONARY) return; - flushPendingWrites(); - // Don't close the database as locale changes will require it to be reopened anyway - // Also, the database is written to somewhat frequently, so it needs to be kept alive - // throughout the life of the process. - // mOpenHelper.close(); - } - - @Override - public void loadDictionaryAsync() { - if (!ENABLE_USER_UNIGRAM_DICTIONARY) return; - // Load the words that correspond to the current input locale - final Cursor cursor = query(COLUMN_LOCALE + "=?", new String[] { mLocale }); - if (null == cursor) return; - try { - if (cursor.moveToFirst()) { - int wordIndex = cursor.getColumnIndex(COLUMN_WORD); - int frequencyIndex = cursor.getColumnIndex(COLUMN_FREQUENCY); - while (!cursor.isAfterLast()) { - String word = cursor.getString(wordIndex); - int frequency = cursor.getInt(frequencyIndex); - // Safeguard against adding really long words. Stack may overflow due - // to recursive lookup - if (word.length() < getMaxWordLength()) { - super.addWord(word, frequency); - } - cursor.moveToNext(); - } - } - } finally { - cursor.close(); - } - } - - public void addUnigram(String newWord) { - if (!ENABLE_USER_UNIGRAM_DICTIONARY) return; - final int addFrequency = FREQUENCY_FOR_TYPED; - String word = newWord; - final int length = word.length(); - // Don't add very short or very long words. - if (length < 2 || length > getMaxWordLength()) return; - if (mIme.isAutoCapitalized()) { - // Remove caps before adding - word = Character.toLowerCase(word.charAt(0)) + word.substring(1); - } - int freq = getWordFrequency(word); - freq = freq < 0 ? addFrequency : freq + addFrequency; - super.addWord(word, freq); - - synchronized (mPendingWritesLock) { - // Write a null frequency if it is to be deleted from the db - mPendingWrites.put(word, freq == 0 ? null : new Integer(freq)); - } - } - - /** - * Schedules a background thread to write any pending words to the database. - */ - public void flushPendingWrites() { - if (!ENABLE_USER_UNIGRAM_DICTIONARY) return; - synchronized (mPendingWritesLock) { - // Nothing pending? Return - if (mPendingWrites.isEmpty()) return; - // Create a background thread to write the pending entries - new UpdateDbTask(sOpenHelper, mPendingWrites, mLocale).execute(); - // Create a new map for writing new entries into while the old one is written to db - mPendingWrites = new HashMap<String, Integer>(); - } - } - - /** - * This class helps open, create, and upgrade the database file. - */ - private static class DatabaseHelper extends SQLiteOpenHelper { - - DatabaseHelper(Context context) { - super(context, DATABASE_NAME, null, DATABASE_VERSION); - } - - @Override - public void onCreate(SQLiteDatabase db) { - db.execSQL("CREATE TABLE " + USER_UNIGRAM_DICT_TABLE_NAME + " (" - + COLUMN_ID + " INTEGER PRIMARY KEY," - + COLUMN_WORD + " TEXT," - + COLUMN_FREQUENCY + " INTEGER," - + COLUMN_LOCALE + " TEXT" - + ");"); - } - - @Override - public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { - Log.w("UserUnigramDictionary", "Upgrading database from version " + oldVersion + " to " - + newVersion + ", which will destroy all old data"); - db.execSQL("DROP TABLE IF EXISTS " + USER_UNIGRAM_DICT_TABLE_NAME); - onCreate(db); - } - } - - private static Cursor query(String selection, String[] selectionArgs) { - SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); - qb.setTables(USER_UNIGRAM_DICT_TABLE_NAME); - qb.setProjectionMap(sDictProjectionMap); - - // Get the database and run the query - try { - SQLiteDatabase db = sOpenHelper.getReadableDatabase(); - Cursor c = qb.query(db, null, selection, selectionArgs, null, null, - DEFAULT_SORT_ORDER); - return c; - } catch (android.database.sqlite.SQLiteCantOpenDatabaseException e) { - // Can't open the database : presumably we can't access storage. That may happen - // when the device is wedged; do a best effort to still start the keyboard. - return null; - } - } - - /** - * Async task to write pending words to the database so that it stays in sync with - * the in-memory trie. - */ - private static class UpdateDbTask extends AsyncTask<Void, Void, Void> { - private final HashMap<String, Integer> mMap; - private final DatabaseHelper mDbHelper; - private final String mLocale; - - public UpdateDbTask(DatabaseHelper openHelper, HashMap<String, Integer> pendingWrites, - String locale) { - mMap = pendingWrites; - mLocale = locale; - mDbHelper = openHelper; - } - - @Override - protected Void doInBackground(Void... v) { - SQLiteDatabase db = null; - try { - db = mDbHelper.getWritableDatabase(); - } catch (android.database.sqlite.SQLiteCantOpenDatabaseException e) { - // With no access to the DB, this is moot. Do nothing: we'll exit through the - // test for null == db. - } - if (null == db) return null; - // Write all the entries to the db - Set<Entry<String,Integer>> mEntries = mMap.entrySet(); - for (Entry<String,Integer> entry : mEntries) { - Integer freq = entry.getValue(); - db.delete(USER_UNIGRAM_DICT_TABLE_NAME, COLUMN_WORD + "=? AND " + COLUMN_LOCALE - + "=?", new String[] { entry.getKey(), mLocale }); - if (freq != null) { - db.insert(USER_UNIGRAM_DICT_TABLE_NAME, null, - getContentValues(entry.getKey(), freq, mLocale)); - } - } - return null; - } - - private static ContentValues getContentValues(String word, int frequency, String locale) { - ContentValues values = new ContentValues(4); - values.put(COLUMN_WORD, word); - values.put(COLUMN_FREQUENCY, frequency); - values.put(COLUMN_LOCALE, locale); - return values; - } - } -} diff --git a/java/src/com/android/inputmethod/latin/Utils.java b/java/src/com/android/inputmethod/latin/Utils.java index a7de47c58..708634529 100644 --- a/java/src/com/android/inputmethod/latin/Utils.java +++ b/java/src/com/android/inputmethod/latin/Utils.java @@ -19,9 +19,11 @@ 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; +import android.os.Build; import android.os.Environment; import android.os.Handler; import android.os.HandlerThread; @@ -43,6 +45,7 @@ import java.io.PrintWriter; import java.nio.channels.FileChannel; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.HashMap; public class Utils { private Utils() { @@ -260,8 +263,8 @@ public class Utils { } } - public static void writeBackSpace() { - UsabilityStudyLogUtils.getInstance().write("<backspace>\t0\t0"); + public static void writeBackSpace(int x, int y) { + UsabilityStudyLogUtils.getInstance().write("<backspace>\t" + x + "\t" + y); } public void writeChar(char c, int x, int y) { @@ -465,4 +468,23 @@ public class Utils { if (TextUtils.isEmpty(info)) return null; return info; } + + private static final String HARDWARE_PREFIX = Build.HARDWARE + ","; + private static final HashMap<Integer, String> sDeviceOverrideValueMap = + new HashMap<Integer, String>(); + + public static String getDeviceOverrideValue(Resources res, int overrideResId, String defValue) { + final Integer key = overrideResId; + if (!sDeviceOverrideValueMap.containsKey(key)) { + String overrideValue = defValue; + for (final String element : res.getStringArray(overrideResId)) { + if (element.startsWith(HARDWARE_PREFIX)) { + overrideValue = element.substring(HARDWARE_PREFIX.length()); + break; + } + } + sDeviceOverrideValueMap.put(key, overrideValue); + } + return sDeviceOverrideValueMap.get(key); + } } diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java index a9609310c..9f23f174f 100644 --- a/java/src/com/android/inputmethod/latin/WordComposer.java +++ b/java/src/com/android/inputmethod/latin/WordComposer.java @@ -140,8 +140,9 @@ public class WordComposer { keyX = x; keyY = y; } else { - codes = keyDetector.newCodeArray(); - keyDetector.getNearbyCodes(x, y, codes); + final Key key = keyDetector.detectHitKey(x, y); + // TODO: Pass an integer instead of an integer array + codes = new int[] { key != null ? key.mCode : NOT_A_CODE }; keyX = keyDetector.getTouchX(x); keyY = keyDetector.getTouchY(y); } @@ -202,9 +203,8 @@ public class WordComposer { if (key.mCode == codePoint) { final int x = key.mX + key.mWidth / 2; final int y = key.mY + key.mHeight / 2; - final int[] codes = keyDetector.newCodeArray(); - keyDetector.getNearbyCodes(x, y, codes); - add(codePoint, codes, x, y); + // TODO: Pass an integer instead of an integer array + add(codePoint, new int[] { key.mCode }, x, y); return; } } @@ -216,7 +216,7 @@ public class WordComposer { * Set the currently composing word to the one passed as an argument. * This will register NOT_A_COORDINATE for X and Ys, and use the passed keyboard for proximity. */ - public void setComposingWord(final CharSequence word, final Keyboard keyboard, + private void setComposingWord(final CharSequence word, final Keyboard keyboard, final KeyDetector keyDetector) { reset(); final int length = word.length(); @@ -233,7 +233,6 @@ public class WordComposer { final KeyDetector keyDetector = new KeyDetector(0); keyDetector.setKeyboard(keyboard, 0, 0); keyDetector.setProximityCorrectionEnabled(true); - keyDetector.setProximityThreshold(keyboard.mMostCommonKeyWidth); setComposingWord(word, keyboard, keyDetector); } diff --git a/java/src/com/android/inputmethod/latin/XmlParseUtils.java b/java/src/com/android/inputmethod/latin/XmlParseUtils.java index e14c71cb5..481cdfa47 100644 --- a/java/src/com/android/inputmethod/latin/XmlParseUtils.java +++ b/java/src/com/android/inputmethod/latin/XmlParseUtils.java @@ -24,6 +24,10 @@ import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; public class XmlParseUtils { + private XmlParseUtils() { + // This utility class is not publicly instantiable. + } + @SuppressWarnings("serial") public static class ParseException extends XmlPullParserException { public ParseException(String msg, XmlPullParser parser) { diff --git a/java/src/com/android/inputmethod/latin/makedict/Dummy.java b/java/src/com/android/inputmethod/latin/makedict/Dummy.java new file mode 100644 index 000000000..27ea5ace6 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/makedict/Dummy.java @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.latin.makedict; + +public class Dummy { + +} diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java index f6c1b163c..06fda44fa 100644 --- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java +++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java @@ -65,7 +65,6 @@ import com.android.inputmethod.latin.SuggestedWords; import com.android.inputmethod.latin.Utils; import java.util.ArrayList; -import java.util.List; public class SuggestionsView extends RelativeLayout implements OnClickListener, OnLongClickListener { @@ -143,9 +142,9 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener, public final float mMinMoreSuggestionsWidth; public final int mMoreSuggestionsBottomGap; - private final List<TextView> mWords; - private final List<View> mDividers; - private final List<TextView> mInfos; + private final ArrayList<TextView> mWords; + private final ArrayList<View> mDividers; + private final ArrayList<TextView> mInfos; private final int mColorValidTypedWord; private final int mColorTypedWord; @@ -173,7 +172,7 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener, private final TextView mHintToSaveView; public SuggestionsViewParams(Context context, AttributeSet attrs, int defStyle, - List<TextView> words, List<View> dividers, List<TextView> infos) { + ArrayList<TextView> words, ArrayList<View> dividers, ArrayList<TextView> infos) { mWords = words; mDividers = dividers; mInfos = infos; |