Loading java/src/com/android/inputmethod/latin/ContactsDictionary.java +1 −1 Original line number Diff line number Diff line Loading @@ -159,7 +159,7 @@ public class ContactsDictionary extends ExpandableDictionary { super.addWord(word, null /* shortcut */, FREQUENCY_FOR_CONTACTS); if (!TextUtils.isEmpty(prevWord)) { super.setBigram(prevWord, word, super.setBigramAndGetFrequency(prevWord, word, FREQUENCY_FOR_CONTACTS_BIGRAM); } prevWord = word; Loading java/src/com/android/inputmethod/latin/ExpandableDictionary.java +100 −36 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.content.Context; import com.android.inputmethod.keyboard.KeyDetector; import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.ProximityInfo; import com.android.inputmethod.latin.UserHistoryForgettingCurveUtils.ForgettingCurveParams; import java.util.ArrayList; import java.util.LinkedList; Loading Loading @@ -80,31 +81,73 @@ public class ExpandableDictionary extends Dictionary { } } private static class NextWord { public final Node mWord; private int mFrequency; protected interface NextWord { public Node getWordNode(); public int getFrequency(); /** FcValue is a bit set */ public int getFcValue(); public int notifyTypedAgainAndGetFrequency(); } public NextWord(Node word, int frequency) { private static class NextStaticWord implements NextWord { public final Node mWord; private final int mFrequency; public NextStaticWord(Node word, int frequency) { mWord = word; mFrequency = frequency; } @Override public Node getWordNode() { return mWord; } @Override public int getFrequency() { return mFrequency; } public int setFrequency(int freq) { mFrequency = freq; @Override public int getFcValue() { return mFrequency; } public int addFrequency(int add) { mFrequency += add; if (mFrequency > BIGRAM_MAX_FREQUENCY) mFrequency = BIGRAM_MAX_FREQUENCY; @Override public int notifyTypedAgainAndGetFrequency() { return mFrequency; } } private static class NextHistoryWord implements NextWord { public final Node mWord; public final ForgettingCurveParams mFcp; public NextHistoryWord(Node word, ForgettingCurveParams fcp) { mWord = word; mFcp = fcp; } @Override public Node getWordNode() { return mWord; } @Override public int getFrequency() { return mFcp.getFrequency(); } @Override public int getFcValue() { return mFcp.getFc(); } @Override public int notifyTypedAgainAndGetFrequency() { return mFcp.notifyTypedAgainAndGetFrequency(); } } private NodeArray mRoots; private int[][] mCodes; Loading Loading @@ -183,7 +226,7 @@ public class ExpandableDictionary extends Dictionary { childNode.mShortcutOnly = isShortcutOnly; children.add(childNode); } if (wordLength == depth + 1) { if (wordLength == depth + 1 && shortcutTarget != null) { // Terminate this word childNode.mTerminal = true; if (isShortcutOnly) { Loading Loading @@ -221,7 +264,7 @@ public class ExpandableDictionary extends Dictionary { protected final void getWordsInner(final WordComposer codes, final CharSequence prevWordForBigrams, final WordCallback callback, @SuppressWarnings("unused") final ProximityInfo proximityInfo) { final ProximityInfo proximityInfo) { mInputLength = codes.size(); if (mCodes.length < mInputLength) mCodes = new int[mInputLength][]; final int[] xCoordinates = codes.getXCoordinates(); Loading Loading @@ -265,13 +308,13 @@ public class ExpandableDictionary extends Dictionary { // Refer to addOrSetBigram() about word1.toLowerCase() final Node firstWord = searchWord(mRoots, word1.toLowerCase(), 0, null); final Node secondWord = searchWord(mRoots, word2, 0, null); LinkedList<NextWord> bigram = firstWord.mNGrams; LinkedList<NextWord> bigrams = firstWord.mNGrams; NextWord bigramNode = null; if (bigram == null || bigram.size() == 0) { if (bigrams == null || bigrams.size() == 0) { return false; } else { for (NextWord nw : bigram) { if (nw.mWord == secondWord) { for (NextWord nw : bigrams) { if (nw.getWordNode() == secondWord) { bigramNode = nw; break; } Loading @@ -280,7 +323,7 @@ public class ExpandableDictionary extends Dictionary { if (bigramNode == null) { return false; } return bigram.remove(bigramNode); return bigrams.remove(bigramNode); } /** Loading @@ -292,6 +335,23 @@ public class ExpandableDictionary extends Dictionary { return (node == null) ? -1 : node.mFrequency; } protected NextWord getBigramWord(String word1, String word2) { // Refer to addOrSetBigram() about word1.toLowerCase() final Node firstWord = searchWord(mRoots, word1.toLowerCase(), 0, null); final Node secondWord = searchWord(mRoots, word2, 0, null); LinkedList<NextWord> bigrams = firstWord.mNGrams; if (bigrams == null || bigrams.size() == 0) { return null; } else { for (NextWord nw : bigrams) { if (nw.getWordNode() == secondWord) { return nw; } } } return null; } private static int computeSkippedWordFinalFreq(int freq, int snr, int inputLength) { // The computation itself makes sense for >= 2, but the == 2 case returns 0 // anyway so we may as well test against 3 instead and return the constant Loading Loading @@ -445,43 +505,45 @@ public class ExpandableDictionary extends Dictionary { } } protected int setBigram(String word1, String word2, int frequency) { return addOrSetBigram(word1, word2, frequency, false); public int setBigramAndGetFrequency(String word1, String word2, int frequency) { return setBigramAndGetFrequency(word1, word2, frequency, null /* unused */); } protected int addBigram(String word1, String word2, int frequency) { return addOrSetBigram(word1, word2, frequency, true); public int setBigramAndGetFrequency(String word1, String word2, ForgettingCurveParams fcp) { return setBigramAndGetFrequency(word1, word2, 0 /* unused */, fcp); } /** * Adds bigrams to the in-memory trie structure that is being used to retrieve any word * @param frequency frequency for this bigram * @param addFrequency if true, it adds to current frequency, else it overwrites the old value * @return returns the final frequency * @return returns the final bigram frequency */ private int addOrSetBigram(String word1, String word2, int frequency, boolean addFrequency) { private int setBigramAndGetFrequency( String word1, String word2, int frequency, ForgettingCurveParams fcp) { // We don't want results to be different according to case of the looked up left hand side // word. We do want however to return the correct case for the right hand side. // So we want to squash the case of the left hand side, and preserve that of the right // hand side word. Node firstWord = searchWord(mRoots, word1.toLowerCase(), 0, null); Node secondWord = searchWord(mRoots, word2, 0, null); LinkedList<NextWord> bigram = firstWord.mNGrams; if (bigram == null || bigram.size() == 0) { LinkedList<NextWord> bigrams = firstWord.mNGrams; if (bigrams == null || bigrams.size() == 0) { firstWord.mNGrams = new LinkedList<NextWord>(); bigram = firstWord.mNGrams; } else { for (NextWord nw : bigram) { if (nw.mWord == secondWord) { if (addFrequency) { return nw.addFrequency(frequency); bigrams = firstWord.mNGrams; } else { return nw.setFrequency(frequency); for (NextWord nw : bigrams) { if (nw.getWordNode() == secondWord) { return nw.notifyTypedAgainAndGetFrequency(); } } } if (fcp != null) { // history firstWord.mNGrams.add(new NextHistoryWord(secondWord, fcp)); } else { firstWord.mNGrams.add(new NextStaticWord(secondWord, frequency)); } firstWord.mNGrams.add(new NextWord(secondWord, frequency)); return frequency; } Loading Loading @@ -580,7 +642,7 @@ public class ExpandableDictionary extends Dictionary { Node node; int freq; for (NextWord nextWord : terminalNodes) { node = nextWord.mWord; node = nextWord.getWordNode(); freq = nextWord.getFrequency(); int index = BinaryDictionary.MAX_WORD_LENGTH; do { Loading @@ -589,10 +651,12 @@ public class ExpandableDictionary extends Dictionary { node = node.mParent; } while (node != null); if (freq >= 0) { callback.addWord(mLookedUpString, index, BinaryDictionary.MAX_WORD_LENGTH - index, freq, mDicTypeId, Dictionary.BIGRAM); } } } /** * Recursively search for the terminal node of the word. Loading java/src/com/android/inputmethod/latin/LatinIME.java +1 −2 Original line number Diff line number Diff line Loading @@ -496,7 +496,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen resetContactsDictionary(oldContactsDictionary); mUserHistoryDictionary = new UserHistoryDictionary( this, localeStr, Suggest.DIC_USER_HISTORY); this, localeStr, Suggest.DIC_USER_HISTORY, mPrefs); mSuggest.setUserHistoryDictionary(mUserHistoryDictionary); } Loading Loading @@ -747,7 +747,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen KeyboardView inputView = mKeyboardSwitcher.getKeyboardView(); if (inputView != null) inputView.closing(); if (mUserHistoryDictionary != null) mUserHistoryDictionary.flushPendingWrites(); } private void onFinishInputViewInternal(boolean finishingInput) { Loading java/src/com/android/inputmethod/latin/Settings.java +2 −1 Original line number Diff line number Diff line Loading @@ -58,6 +58,8 @@ public class Settings extends InputMethodSettingsFragment public static final String PREF_SHOW_SUGGESTIONS_SETTING = "show_suggestions_setting"; public static final String PREF_MISC_SETTINGS = "misc_settings"; public static final String PREF_USABILITY_STUDY_MODE = "usability_study_mode"; public static final String PREF_LAST_USER_DICTIONARY_WRITE_TIME = "last_user_dictionary_write_time"; public static final String PREF_ADVANCED_SETTINGS = "pref_advanced_settings"; public static final String PREF_SUPPRESS_LANGUAGE_SWITCH_KEY = "pref_suppress_language_switch_key"; Loading Loading @@ -244,7 +246,6 @@ public class Settings extends InputMethodSettingsFragment refreshEnablingsOfKeypressSoundAndVibrationSettings(prefs, res); } @SuppressWarnings("unused") @Override public void onResume() { super.onResume(); Loading java/src/com/android/inputmethod/latin/SettingsValues.java +21 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,8 @@ import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Map; /** * When you call the constructor of this class, you may want to change the current system locale by Loading Loading @@ -351,4 +353,23 @@ public class SettingsValues { // TODO: use mUsabilityStudyMode instead of reading it again here return prefs.getBoolean(Settings.PREF_USABILITY_STUDY_MODE, true); } public static long getLastUserHistoryWriteTime( final SharedPreferences prefs, final String locale) { final String str = prefs.getString(Settings.PREF_LAST_USER_DICTIONARY_WRITE_TIME, ""); final HashMap<String, Long> map = Utils.localeAndTimeStrToHashMap(str); if (map.containsKey(locale)) { return map.get(locale); } return 0; } public static void setLastUserHistoryWriteTime( final SharedPreferences prefs, final String locale) { final String oldStr = prefs.getString(Settings.PREF_LAST_USER_DICTIONARY_WRITE_TIME, ""); final HashMap<String, Long> map = Utils.localeAndTimeStrToHashMap(oldStr); map.put(locale, System.currentTimeMillis()); final String newStr = Utils.localeAndTimeHashMapToStr(map); prefs.edit().putString(Settings.PREF_LAST_USER_DICTIONARY_WRITE_TIME, newStr).apply(); } } Loading
java/src/com/android/inputmethod/latin/ContactsDictionary.java +1 −1 Original line number Diff line number Diff line Loading @@ -159,7 +159,7 @@ public class ContactsDictionary extends ExpandableDictionary { super.addWord(word, null /* shortcut */, FREQUENCY_FOR_CONTACTS); if (!TextUtils.isEmpty(prevWord)) { super.setBigram(prevWord, word, super.setBigramAndGetFrequency(prevWord, word, FREQUENCY_FOR_CONTACTS_BIGRAM); } prevWord = word; Loading
java/src/com/android/inputmethod/latin/ExpandableDictionary.java +100 −36 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.content.Context; import com.android.inputmethod.keyboard.KeyDetector; import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.ProximityInfo; import com.android.inputmethod.latin.UserHistoryForgettingCurveUtils.ForgettingCurveParams; import java.util.ArrayList; import java.util.LinkedList; Loading Loading @@ -80,31 +81,73 @@ public class ExpandableDictionary extends Dictionary { } } private static class NextWord { public final Node mWord; private int mFrequency; protected interface NextWord { public Node getWordNode(); public int getFrequency(); /** FcValue is a bit set */ public int getFcValue(); public int notifyTypedAgainAndGetFrequency(); } public NextWord(Node word, int frequency) { private static class NextStaticWord implements NextWord { public final Node mWord; private final int mFrequency; public NextStaticWord(Node word, int frequency) { mWord = word; mFrequency = frequency; } @Override public Node getWordNode() { return mWord; } @Override public int getFrequency() { return mFrequency; } public int setFrequency(int freq) { mFrequency = freq; @Override public int getFcValue() { return mFrequency; } public int addFrequency(int add) { mFrequency += add; if (mFrequency > BIGRAM_MAX_FREQUENCY) mFrequency = BIGRAM_MAX_FREQUENCY; @Override public int notifyTypedAgainAndGetFrequency() { return mFrequency; } } private static class NextHistoryWord implements NextWord { public final Node mWord; public final ForgettingCurveParams mFcp; public NextHistoryWord(Node word, ForgettingCurveParams fcp) { mWord = word; mFcp = fcp; } @Override public Node getWordNode() { return mWord; } @Override public int getFrequency() { return mFcp.getFrequency(); } @Override public int getFcValue() { return mFcp.getFc(); } @Override public int notifyTypedAgainAndGetFrequency() { return mFcp.notifyTypedAgainAndGetFrequency(); } } private NodeArray mRoots; private int[][] mCodes; Loading Loading @@ -183,7 +226,7 @@ public class ExpandableDictionary extends Dictionary { childNode.mShortcutOnly = isShortcutOnly; children.add(childNode); } if (wordLength == depth + 1) { if (wordLength == depth + 1 && shortcutTarget != null) { // Terminate this word childNode.mTerminal = true; if (isShortcutOnly) { Loading Loading @@ -221,7 +264,7 @@ public class ExpandableDictionary extends Dictionary { protected final void getWordsInner(final WordComposer codes, final CharSequence prevWordForBigrams, final WordCallback callback, @SuppressWarnings("unused") final ProximityInfo proximityInfo) { final ProximityInfo proximityInfo) { mInputLength = codes.size(); if (mCodes.length < mInputLength) mCodes = new int[mInputLength][]; final int[] xCoordinates = codes.getXCoordinates(); Loading Loading @@ -265,13 +308,13 @@ public class ExpandableDictionary extends Dictionary { // Refer to addOrSetBigram() about word1.toLowerCase() final Node firstWord = searchWord(mRoots, word1.toLowerCase(), 0, null); final Node secondWord = searchWord(mRoots, word2, 0, null); LinkedList<NextWord> bigram = firstWord.mNGrams; LinkedList<NextWord> bigrams = firstWord.mNGrams; NextWord bigramNode = null; if (bigram == null || bigram.size() == 0) { if (bigrams == null || bigrams.size() == 0) { return false; } else { for (NextWord nw : bigram) { if (nw.mWord == secondWord) { for (NextWord nw : bigrams) { if (nw.getWordNode() == secondWord) { bigramNode = nw; break; } Loading @@ -280,7 +323,7 @@ public class ExpandableDictionary extends Dictionary { if (bigramNode == null) { return false; } return bigram.remove(bigramNode); return bigrams.remove(bigramNode); } /** Loading @@ -292,6 +335,23 @@ public class ExpandableDictionary extends Dictionary { return (node == null) ? -1 : node.mFrequency; } protected NextWord getBigramWord(String word1, String word2) { // Refer to addOrSetBigram() about word1.toLowerCase() final Node firstWord = searchWord(mRoots, word1.toLowerCase(), 0, null); final Node secondWord = searchWord(mRoots, word2, 0, null); LinkedList<NextWord> bigrams = firstWord.mNGrams; if (bigrams == null || bigrams.size() == 0) { return null; } else { for (NextWord nw : bigrams) { if (nw.getWordNode() == secondWord) { return nw; } } } return null; } private static int computeSkippedWordFinalFreq(int freq, int snr, int inputLength) { // The computation itself makes sense for >= 2, but the == 2 case returns 0 // anyway so we may as well test against 3 instead and return the constant Loading Loading @@ -445,43 +505,45 @@ public class ExpandableDictionary extends Dictionary { } } protected int setBigram(String word1, String word2, int frequency) { return addOrSetBigram(word1, word2, frequency, false); public int setBigramAndGetFrequency(String word1, String word2, int frequency) { return setBigramAndGetFrequency(word1, word2, frequency, null /* unused */); } protected int addBigram(String word1, String word2, int frequency) { return addOrSetBigram(word1, word2, frequency, true); public int setBigramAndGetFrequency(String word1, String word2, ForgettingCurveParams fcp) { return setBigramAndGetFrequency(word1, word2, 0 /* unused */, fcp); } /** * Adds bigrams to the in-memory trie structure that is being used to retrieve any word * @param frequency frequency for this bigram * @param addFrequency if true, it adds to current frequency, else it overwrites the old value * @return returns the final frequency * @return returns the final bigram frequency */ private int addOrSetBigram(String word1, String word2, int frequency, boolean addFrequency) { private int setBigramAndGetFrequency( String word1, String word2, int frequency, ForgettingCurveParams fcp) { // We don't want results to be different according to case of the looked up left hand side // word. We do want however to return the correct case for the right hand side. // So we want to squash the case of the left hand side, and preserve that of the right // hand side word. Node firstWord = searchWord(mRoots, word1.toLowerCase(), 0, null); Node secondWord = searchWord(mRoots, word2, 0, null); LinkedList<NextWord> bigram = firstWord.mNGrams; if (bigram == null || bigram.size() == 0) { LinkedList<NextWord> bigrams = firstWord.mNGrams; if (bigrams == null || bigrams.size() == 0) { firstWord.mNGrams = new LinkedList<NextWord>(); bigram = firstWord.mNGrams; } else { for (NextWord nw : bigram) { if (nw.mWord == secondWord) { if (addFrequency) { return nw.addFrequency(frequency); bigrams = firstWord.mNGrams; } else { return nw.setFrequency(frequency); for (NextWord nw : bigrams) { if (nw.getWordNode() == secondWord) { return nw.notifyTypedAgainAndGetFrequency(); } } } if (fcp != null) { // history firstWord.mNGrams.add(new NextHistoryWord(secondWord, fcp)); } else { firstWord.mNGrams.add(new NextStaticWord(secondWord, frequency)); } firstWord.mNGrams.add(new NextWord(secondWord, frequency)); return frequency; } Loading Loading @@ -580,7 +642,7 @@ public class ExpandableDictionary extends Dictionary { Node node; int freq; for (NextWord nextWord : terminalNodes) { node = nextWord.mWord; node = nextWord.getWordNode(); freq = nextWord.getFrequency(); int index = BinaryDictionary.MAX_WORD_LENGTH; do { Loading @@ -589,10 +651,12 @@ public class ExpandableDictionary extends Dictionary { node = node.mParent; } while (node != null); if (freq >= 0) { callback.addWord(mLookedUpString, index, BinaryDictionary.MAX_WORD_LENGTH - index, freq, mDicTypeId, Dictionary.BIGRAM); } } } /** * Recursively search for the terminal node of the word. Loading
java/src/com/android/inputmethod/latin/LatinIME.java +1 −2 Original line number Diff line number Diff line Loading @@ -496,7 +496,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen resetContactsDictionary(oldContactsDictionary); mUserHistoryDictionary = new UserHistoryDictionary( this, localeStr, Suggest.DIC_USER_HISTORY); this, localeStr, Suggest.DIC_USER_HISTORY, mPrefs); mSuggest.setUserHistoryDictionary(mUserHistoryDictionary); } Loading Loading @@ -747,7 +747,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen KeyboardView inputView = mKeyboardSwitcher.getKeyboardView(); if (inputView != null) inputView.closing(); if (mUserHistoryDictionary != null) mUserHistoryDictionary.flushPendingWrites(); } private void onFinishInputViewInternal(boolean finishingInput) { Loading
java/src/com/android/inputmethod/latin/Settings.java +2 −1 Original line number Diff line number Diff line Loading @@ -58,6 +58,8 @@ public class Settings extends InputMethodSettingsFragment public static final String PREF_SHOW_SUGGESTIONS_SETTING = "show_suggestions_setting"; public static final String PREF_MISC_SETTINGS = "misc_settings"; public static final String PREF_USABILITY_STUDY_MODE = "usability_study_mode"; public static final String PREF_LAST_USER_DICTIONARY_WRITE_TIME = "last_user_dictionary_write_time"; public static final String PREF_ADVANCED_SETTINGS = "pref_advanced_settings"; public static final String PREF_SUPPRESS_LANGUAGE_SWITCH_KEY = "pref_suppress_language_switch_key"; Loading Loading @@ -244,7 +246,6 @@ public class Settings extends InputMethodSettingsFragment refreshEnablingsOfKeypressSoundAndVibrationSettings(prefs, res); } @SuppressWarnings("unused") @Override public void onResume() { super.onResume(); Loading
java/src/com/android/inputmethod/latin/SettingsValues.java +21 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,8 @@ import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Map; /** * When you call the constructor of this class, you may want to change the current system locale by Loading Loading @@ -351,4 +353,23 @@ public class SettingsValues { // TODO: use mUsabilityStudyMode instead of reading it again here return prefs.getBoolean(Settings.PREF_USABILITY_STUDY_MODE, true); } public static long getLastUserHistoryWriteTime( final SharedPreferences prefs, final String locale) { final String str = prefs.getString(Settings.PREF_LAST_USER_DICTIONARY_WRITE_TIME, ""); final HashMap<String, Long> map = Utils.localeAndTimeStrToHashMap(str); if (map.containsKey(locale)) { return map.get(locale); } return 0; } public static void setLastUserHistoryWriteTime( final SharedPreferences prefs, final String locale) { final String oldStr = prefs.getString(Settings.PREF_LAST_USER_DICTIONARY_WRITE_TIME, ""); final HashMap<String, Long> map = Utils.localeAndTimeStrToHashMap(oldStr); map.put(locale, System.currentTimeMillis()); final String newStr = Utils.localeAndTimeHashMapToStr(map); prefs.edit().putString(Settings.PREF_LAST_USER_DICTIONARY_WRITE_TIME, newStr).apply(); } }