diff options
Diffstat (limited to 'java/src/com/android/inputmethod/latin')
20 files changed, 204 insertions, 176 deletions
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java index 1e31c96ec..b8cf3f89c 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java @@ -113,11 +113,8 @@ public final class BinaryDictionary extends Dictionary { synchronized(mDicTraverseSessions) { DicTraverseSession traverseSession = mDicTraverseSessions.get(traverseSessionId); if (traverseSession == null) { - traverseSession = mDicTraverseSessions.get(traverseSessionId); - if (traverseSession == null) { - traverseSession = new DicTraverseSession(mLocale, mNativeDict, mDictSize); - mDicTraverseSessions.put(traverseSessionId, traverseSession); - } + traverseSession = new DicTraverseSession(mLocale, mNativeDict, mDictSize); + mDicTraverseSessions.put(traverseSessionId, traverseSession); } return traverseSession; } @@ -266,19 +263,9 @@ public final class BinaryDictionary extends Dictionary { new FormatSpec.FormatOptions(outFormatVersion[0], hasHistoricalInfo)); } - @Override public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, - final String prevWord, final ProximityInfo proximityInfo, - final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, - final float[] inOutLanguageWeight) { - return getSuggestionsWithSessionId(composer, prevWord, proximityInfo, blockOffensiveWords, - additionalFeaturesOptions, 0 /* sessionId */, inOutLanguageWeight); - } - - @Override - public ArrayList<SuggestedWordInfo> getSuggestionsWithSessionId(final WordComposer composer, - final String prevWord, final ProximityInfo proximityInfo, + final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, final int sessionId, final float[] inOutLanguageWeight) { if (!isValidDictionary()) { @@ -287,8 +274,8 @@ public final class BinaryDictionary extends Dictionary { Arrays.fill(mInputCodePoints, Constants.NOT_A_CODE); // TODO: toLowerCase in the native code - final int[] prevWordCodePointArray = (null == prevWord) - ? null : StringUtils.toCodePointArray(prevWord); + final int[] prevWordCodePointArray = (null == prevWordsInfo.mPrevWord) + ? null : StringUtils.toCodePointArray(prevWordsInfo.mPrevWord); final InputPointers inputPointers = composer.getInputPointers(); final boolean isGesture = composer.isBatchMode(); final int inputSize; diff --git a/java/src/com/android/inputmethod/latin/Dictionary.java b/java/src/com/android/inputmethod/latin/Dictionary.java index cd380db6b..aab16653e 100644 --- a/java/src/com/android/inputmethod/latin/Dictionary.java +++ b/java/src/com/android/inputmethod/latin/Dictionary.java @@ -69,31 +69,20 @@ public abstract class Dictionary { * Searches for suggestions for a given context. For the moment the context is only the * previous word. * @param composer the key sequence to match with coordinate info, as a WordComposer - * @param prevWord the previous word, or null if none + * @param prevWordsInfo the information of previous words. * @param proximityInfo the object for key proximity. May be ignored by some implementations. * @param blockOffensiveWords whether to block potentially offensive words * @param additionalFeaturesOptions options about additional features used for the suggestion. + * @param sessionId the session id. * @param inOutLanguageWeight the language weight used for generating suggestions. * inOutLanguageWeight is a float array that has only one element. This can be updated when the * different language weight is used. * @return the list of suggestions (possibly null if none) */ - // TODO: pass more context than just the previous word, to enable better suggestions (n-gram - // and more) abstract public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, - final String prevWord, final ProximityInfo proximityInfo, + final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, - final float[] inOutLanguageWeight); - - // The default implementation of this method ignores sessionId. - // Subclasses that want to use sessionId need to override this method. - public ArrayList<SuggestedWordInfo> getSuggestionsWithSessionId(final WordComposer composer, - final String prevWord, final ProximityInfo proximityInfo, - final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, - final int sessionId, final float[] inOutLanguageWeight) { - return getSuggestions(composer, prevWord, proximityInfo, blockOffensiveWords, - additionalFeaturesOptions, inOutLanguageWeight); - } + final int sessionId, final float[] inOutLanguageWeight); /** * Checks if the given word occurs in the dictionary @@ -165,9 +154,9 @@ public abstract class Dictionary { @Override public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, - final String prevWord, final ProximityInfo proximityInfo, + final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, - final float[] inOutLanguageWeight) { + final int sessionId, final float[] inOutLanguageWeight) { return null; } diff --git a/java/src/com/android/inputmethod/latin/DictionaryCollection.java b/java/src/com/android/inputmethod/latin/DictionaryCollection.java index 16173fffc..e6e4e0938 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryCollection.java +++ b/java/src/com/android/inputmethod/latin/DictionaryCollection.java @@ -57,22 +57,22 @@ public final class DictionaryCollection extends Dictionary { @Override public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, - final String prevWord, final ProximityInfo proximityInfo, + final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, - final float[] inOutLanguageWeight) { + final int sessionId, final float[] inOutLanguageWeight) { final CopyOnWriteArrayList<Dictionary> dictionaries = mDictionaries; if (dictionaries.isEmpty()) return null; // To avoid creating unnecessary objects, we get the list out of the first // dictionary and add the rest to it if not null, hence the get(0) ArrayList<SuggestedWordInfo> suggestions = dictionaries.get(0).getSuggestions(composer, - prevWord, proximityInfo, blockOffensiveWords, additionalFeaturesOptions, - inOutLanguageWeight); + prevWordsInfo, proximityInfo, blockOffensiveWords, additionalFeaturesOptions, + sessionId, inOutLanguageWeight); if (null == suggestions) suggestions = CollectionUtils.newArrayList(); final int length = dictionaries.size(); for (int i = 1; i < length; ++ i) { final ArrayList<SuggestedWordInfo> sugg = dictionaries.get(i).getSuggestions(composer, - prevWord, proximityInfo, blockOffensiveWords, additionalFeaturesOptions, - inOutLanguageWeight); + prevWordsInfo, proximityInfo, blockOffensiveWords, additionalFeaturesOptions, + sessionId, inOutLanguageWeight); if (null != sugg) suggestions.addAll(sugg); } return suggestions; diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java index e0220e137..14c8bb6c3 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java @@ -444,7 +444,7 @@ public class DictionaryFacilitatorForSuggest { // TODO: Revise the way to fusion suggestion results. public SuggestionResults getSuggestionResults(final WordComposer composer, - final String prevWord, final ProximityInfo proximityInfo, + final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, final int sessionId, final ArrayList<SuggestedWordInfo> rawSuggestions) { final Dictionaries dictionaries = mDictionaries; @@ -455,7 +455,7 @@ public class DictionaryFacilitatorForSuggest { final Dictionary dictionary = dictionaries.getDict(dictType); if (null == dictionary) continue; final ArrayList<SuggestedWordInfo> dictionarySuggestions = - dictionary.getSuggestionsWithSessionId(composer, prevWord, proximityInfo, + dictionary.getSuggestions(composer, prevWordsInfo, proximityInfo, blockOffensiveWords, additionalFeaturesOptions, sessionId, languageWeight); if (null == dictionarySuggestions) continue; diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java index e323f0ab2..629f3fd18 100644 --- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java @@ -366,8 +366,8 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { } @Override - public ArrayList<SuggestedWordInfo> getSuggestionsWithSessionId(final WordComposer composer, - final String prevWord, final ProximityInfo proximityInfo, + public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, + final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, final int sessionId, final float[] inOutLanguageWeight) { reloadDictionaryIfRequired(); @@ -380,9 +380,9 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { return null; } final ArrayList<SuggestedWordInfo> suggestions = - mBinaryDictionary.getSuggestionsWithSessionId(composer, prevWord, - proximityInfo, blockOffensiveWords, additionalFeaturesOptions, - sessionId, inOutLanguageWeight); + mBinaryDictionary.getSuggestions(composer, prevWordsInfo, proximityInfo, + blockOffensiveWords, additionalFeaturesOptions, sessionId, + inOutLanguageWeight); if (mBinaryDictionary.isCorrupted()) { Log.i(TAG, "Dictionary (" + mDictName +") is corrupted. " + "Remove and regenerate it."); @@ -401,15 +401,6 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { } @Override - public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, - final String prevWord, final ProximityInfo proximityInfo, - final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, - final float[] inOutLanguageWeight) { - return getSuggestionsWithSessionId(composer, prevWord, proximityInfo, blockOffensiveWords, - additionalFeaturesOptions, 0 /* sessionId */, inOutLanguageWeight); - } - - @Override public boolean isValidWord(final String word) { reloadDictionaryIfRequired(); boolean lockAcquired = false; diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 1ccf5854a..5e45275f8 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -140,10 +140,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private final SubtypeState mSubtypeState = new SubtypeState(); // Object for reacting to adding/removing a dictionary pack. - private BroadcastReceiver mDictionaryPackInstallReceiver = + private final BroadcastReceiver mDictionaryPackInstallReceiver = new DictionaryPackInstallBroadcastReceiver(this); - private BroadcastReceiver mDictionaryDumpBroadcastReceiver = + private final BroadcastReceiver mDictionaryDumpBroadcastReceiver = new DictionaryDumpBroadcastReceiver(this); private AlertDialog mOptionsDialog; @@ -905,7 +905,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private void onFinishInputViewInternal(final boolean finishingInput) { super.onFinishInputView(finishingInput); - mKeyboardSwitcher.onFinishInputView(); mKeyboardSwitcher.deallocateMemory(); // Remove pending messages related to update suggestions mHandler.cancelUpdateSuggestionStrip(); @@ -1388,7 +1387,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen if (!hasSuggestionStripView()) { return; } - mKeyboardSwitcher.onAutoCorrectionStateChanged(suggestedWords.mWillAutoCorrect); if (!onEvaluateInputViewShown()) { return; } @@ -1430,8 +1428,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen if (DEBUG) { if (mInputLogic.mWordComposer.isComposingWord() || mInputLogic.mWordComposer.isBatchMode()) { - final String previousWord - = mInputLogic.mWordComposer.getPreviousWordForSuggestion(); + final PrevWordsInfo prevWordsInfo + = mInputLogic.mWordComposer.getPrevWordsInfoForSuggestion(); // TODO: this is for checking consistency with older versions. Remove this when // we are confident this is stable. // We're checking the previous word in the text field against the memorized previous @@ -1440,14 +1438,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen final CharSequence rereadPrevWord = mInputLogic.getNthPreviousWordForSuggestion( currentSettings.mSpacingAndPunctuations, mInputLogic.mWordComposer.isComposingWord() ? 2 : 1); - if (!TextUtils.equals(previousWord, rereadPrevWord)) { + if (!TextUtils.equals(prevWordsInfo.mPrevWord, rereadPrevWord)) { throw new RuntimeException("Unexpected previous word: " - + previousWord + " <> " + rereadPrevWord); + + prevWordsInfo.mPrevWord + " <> " + rereadPrevWord); } } } mInputLogic.mSuggest.getSuggestedWords(mInputLogic.mWordComposer, - mInputLogic.mWordComposer.getPreviousWordForSuggestion(), + mInputLogic.mWordComposer.getPrevWordsInfoForSuggestion(), keyboard.getProximityInfo(), currentSettings.mBlockPotentiallyOffensive, currentSettings.mCorrectionEnabled, additionalFeaturesOptions, sessionId, sequenceNumber, callback); @@ -1631,7 +1629,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // boolean onKeyMultiple(final int keyCode, final int count, final KeyEvent event); // receive ringer mode change and network state change. - private BroadcastReceiver mConnectivityAndRingerModeChangeReceiver = new BroadcastReceiver() { + private final BroadcastReceiver mConnectivityAndRingerModeChangeReceiver = + new BroadcastReceiver() { @Override public void onReceive(final Context context, final Intent intent) { final String action = intent.getAction(); @@ -1748,8 +1747,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen @UsedForTesting /* package for test */ DistracterFilter createDistracterFilter() { - return DistracterFilterUtils.createDistracterFilter( - mInputLogic.mSuggest, mKeyboardSwitcher); + return DistracterFilterUtils.createDistracterFilter(this /* Context */, mKeyboardSwitcher); } public void dumpDictionaryForDebug(final String dictName) { diff --git a/java/src/com/android/inputmethod/latin/PrevWordsInfo.java b/java/src/com/android/inputmethod/latin/PrevWordsInfo.java new file mode 100644 index 000000000..9d8543183 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/PrevWordsInfo.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2014 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; + +public class PrevWordsInfo { + // The previous word. May be null after resetting and before starting a new composing word, or + // when there is no context like at the start of text for example. It can also be set to null + // externally when the user enters a separator that does not let bigrams across, like a period + // or a comma. + public final String mPrevWord; + + public PrevWordsInfo(final String prevWord) { + mPrevWord = prevWord; + } +} diff --git a/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java index 9f61d6c37..8f744bef8 100644 --- a/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java @@ -50,22 +50,14 @@ public final class ReadOnlyBinaryDictionary extends Dictionary { @Override public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, - final String prevWord, final ProximityInfo proximityInfo, - final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, - final float[] inOutLanguageWeight) { - return getSuggestionsWithSessionId(composer, prevWord, proximityInfo, blockOffensiveWords, - additionalFeaturesOptions, 0 /* sessionId */, inOutLanguageWeight); - } - - @Override - public ArrayList<SuggestedWordInfo> getSuggestionsWithSessionId(final WordComposer composer, - final String prevWord, final ProximityInfo proximityInfo, + final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, final int sessionId, final float[] inOutLanguageWeight) { if (mLock.readLock().tryLock()) { try { - return mBinaryDictionary.getSuggestions(composer, prevWord, proximityInfo, - blockOffensiveWords, additionalFeaturesOptions, inOutLanguageWeight); + return mBinaryDictionary.getSuggestions(composer, prevWordsInfo, proximityInfo, + blockOffensiveWords, additionalFeaturesOptions, sessionId, + inOutLanguageWeight); } finally { mLock.readLock().unlock(); } diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java index db0a8a81c..e3759a586 100644 --- a/java/src/com/android/inputmethod/latin/Suggest.java +++ b/java/src/com/android/inputmethod/latin/Suggest.java @@ -71,17 +71,17 @@ public final class Suggest { } public void getSuggestedWords(final WordComposer wordComposer, - final String prevWordForBigram, final ProximityInfo proximityInfo, + final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, final boolean blockOffensiveWords, final boolean isCorrectionEnabled, final int[] additionalFeaturesOptions, final int sessionId, final int sequenceNumber, final OnGetSuggestedWordsCallback callback) { - LatinImeLogger.onStartSuggestion(prevWordForBigram); + LatinImeLogger.onStartSuggestion(prevWordsInfo.mPrevWord); if (wordComposer.isBatchMode()) { - getSuggestedWordsForBatchInput(wordComposer, prevWordForBigram, proximityInfo, + getSuggestedWordsForBatchInput(wordComposer, prevWordsInfo, proximityInfo, blockOffensiveWords, additionalFeaturesOptions, sessionId, sequenceNumber, callback); } else { - getSuggestedWordsForTypingInput(wordComposer, prevWordForBigram, proximityInfo, + getSuggestedWordsForTypingInput(wordComposer, prevWordsInfo, proximityInfo, blockOffensiveWords, isCorrectionEnabled, additionalFeaturesOptions, sequenceNumber, callback); } @@ -90,12 +90,12 @@ public final class Suggest { // Retrieves suggestions for the typing input // and calls the callback function with the suggestions. private void getSuggestedWordsForTypingInput(final WordComposer wordComposer, - final String prevWordForBigram, final ProximityInfo proximityInfo, + final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, final boolean blockOffensiveWords, final boolean isCorrectionEnabled, final int[] additionalFeaturesOptions, final int sequenceNumber, final OnGetSuggestedWordsCallback callback) { - final int trailingSingleQuotesCount = wordComposer.trailingSingleQuotesCount(); final String typedWord = wordComposer.getTypedWord(); + final int trailingSingleQuotesCount = StringUtils.getTrailingSingleQuotesCount(typedWord); final String consideredWord = trailingSingleQuotesCount > 0 ? typedWord.substring(0, typedWord.length() - trailingSingleQuotesCount) : typedWord; @@ -108,7 +108,7 @@ public final class Suggest { rawSuggestions = null; } final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults( - wordComposer, prevWordForBigram, proximityInfo, blockOffensiveWords, + wordComposer, prevWordsInfo, proximityInfo, blockOffensiveWords, additionalFeaturesOptions, SESSION_TYPING, rawSuggestions); final boolean isFirstCharCapitalized = wordComposer.isFirstCharCapitalized(); @@ -215,7 +215,7 @@ public final class Suggest { // Retrieves suggestions for the batch input // and calls the callback function with the suggestions. private void getSuggestedWordsForBatchInput(final WordComposer wordComposer, - final String prevWordForBigram, final ProximityInfo proximityInfo, + final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, final int sessionId, final int sequenceNumber, final OnGetSuggestedWordsCallback callback) { @@ -226,7 +226,7 @@ public final class Suggest { rawSuggestions = null; } final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults( - wordComposer, prevWordForBigram, proximityInfo, blockOffensiveWords, + wordComposer, prevWordsInfo, proximityInfo, blockOffensiveWords, additionalFeaturesOptions, sessionId, rawSuggestions); for (SuggestedWordInfo wordInfo : suggestionResults) { LatinImeLogger.onAddSuggestedWord(wordInfo.mWord, wordInfo.mSourceDict.mDictType); diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java index ac6972928..227b42bde 100644 --- a/java/src/com/android/inputmethod/latin/WordComposer.java +++ b/java/src/com/android/inputmethod/latin/WordComposer.java @@ -46,11 +46,9 @@ public final class WordComposer { // The list of events that served to compose this string. private final ArrayList<Event> mEvents; private final InputPointers mInputPointers = new InputPointers(MAX_WORD_LENGTH); - // The previous word (before the composing word). Used as context for suggestions. May be null - // after resetting and before starting a new composing word, or when there is no context like - // at the start of text for example. It can also be set to null externally when the user - // enters a separator that does not let bigrams across, like a period or a comma. - private String mPreviousWordForSuggestion; + // The information of previous words (before the composing word). Must not be null. Used as + // context for suggestions. + private PrevWordsInfo mPrevWordsInfo; private String mAutoCorrection; private boolean mIsResumed; private boolean mIsBatchMode; @@ -87,7 +85,7 @@ public final class WordComposer { mIsBatchMode = false; mCursorPositionWithinWord = 0; mRejectedBatchModeSuggestion = null; - mPreviousWordForSuggestion = null; + mPrevWordsInfo = new PrevWordsInfo(null); refreshTypedWordCache(); } @@ -119,7 +117,7 @@ public final class WordComposer { mIsBatchMode = false; mCursorPositionWithinWord = 0; mRejectedBatchModeSuggestion = null; - mPreviousWordForSuggestion = null; + mPrevWordsInfo = new PrevWordsInfo(null); refreshTypedWordCache(); } @@ -149,7 +147,8 @@ public final class WordComposer { public int copyCodePointsExceptTrailingSingleQuotesAndReturnCodePointCount( final int[] destination) { // lastIndex is exclusive - final int lastIndex = mTypedWordCache.length() - trailingSingleQuotesCount(); + final int lastIndex = mTypedWordCache.length() + - StringUtils.getTrailingSingleQuotesCount(mTypedWordCache); if (lastIndex <= 0) { // The string is empty or contains only single quotes. return 0; @@ -308,7 +307,7 @@ public final class WordComposer { CoordinateUtils.yFromArray(coordinates, i))); } mIsResumed = true; - mPreviousWordForSuggestion = null == previousWord ? null : previousWord.toString(); + mPrevWordsInfo = new PrevWordsInfo(null == previousWord ? null : previousWord.toString()); } /** @@ -319,8 +318,8 @@ public final class WordComposer { return mTypedWordCache.toString(); } - public String getPreviousWordForSuggestion() { - return mPreviousWordForSuggestion; + public PrevWordsInfo getPrevWordsInfoForSuggestion() { + return mPrevWordsInfo; } /** @@ -331,15 +330,6 @@ public final class WordComposer { return mIsFirstCharCapitalized; } - public int trailingSingleQuotesCount() { - final int lastIndex = mTypedWordCache.length() - 1; - int i = lastIndex; - while (i >= 0 && mTypedWordCache.charAt(i) == Constants.CODE_SINGLE_QUOTE) { - --i; - } - return lastIndex - i; - } - /** * Whether or not all of the user typed chars are upper case * @return true if all user typed chars are upper case, false otherwise @@ -387,7 +377,7 @@ public final class WordComposer { public void setCapitalizedModeAndPreviousWordAtStartComposingTime(final int mode, final CharSequence previousWord) { mCapitalizedMode = mode; - mPreviousWordForSuggestion = null == previousWord ? null : previousWord.toString(); + mPrevWordsInfo = new PrevWordsInfo(null == previousWord ? null : previousWord.toString()); } /** @@ -438,7 +428,7 @@ public final class WordComposer { mCapsCount = 0; mDigitsCount = 0; mIsBatchMode = false; - mPreviousWordForSuggestion = committedWord.toString(); + mPrevWordsInfo = new PrevWordsInfo(committedWord.toString()); mCombinerChain.reset(); mEvents.clear(); mCodePointSize = 0; @@ -456,11 +446,11 @@ public final class WordComposer { // when the user inputs a separator that's not whitespace (including the case of the // double-space-to-period feature). public void discardPreviousWordForSuggestion() { - mPreviousWordForSuggestion = null; + mPrevWordsInfo = new PrevWordsInfo(null); } public void resumeSuggestionOnLastComposedWord(final LastComposedWord lastComposedWord, - final String previousWord) { + final PrevWordsInfo prevWordsInfo) { mEvents.clear(); Collections.copy(mEvents, lastComposedWord.mEvents); mInputPointers.set(lastComposedWord.mInputPointers); @@ -471,7 +461,7 @@ public final class WordComposer { mCursorPositionWithinWord = mCodePointSize; mRejectedBatchModeSuggestion = null; mIsResumed = true; - mPreviousWordForSuggestion = previousWord; + mPrevWordsInfo = prevWordsInfo; } public boolean isBatchMode() { diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java index afacd085b..6ef505e76 100644 --- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java +++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java @@ -138,11 +138,13 @@ public class PersonalizationHelper { } } dictionaryMap.clear(); - if (!FileUtils.deleteFilteredFiles( - context.getFilesDir(), new DictFilter(dictNamePrefix))) { + final File filesDir = context.getFilesDir(); + if (filesDir == null) { + Log.e(TAG, "context.getFilesDir() returned null."); + } + if (!FileUtils.deleteFilteredFiles(filesDir, new DictFilter(dictNamePrefix))) { Log.e(TAG, "Cannot remove all existing dictionary files. filesDir: " - + context.getFilesDir().getAbsolutePath() + ", dictNamePrefix: " - + dictNamePrefix); + + filesDir.getAbsolutePath() + ", dictNamePrefix: " + dictNamePrefix); } } } diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java index ddda52d71..e951f5a89 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerSession.java @@ -23,6 +23,7 @@ import android.view.textservice.SentenceSuggestionsInfo; import android.view.textservice.SuggestionsInfo; import android.view.textservice.TextInfo; +import com.android.inputmethod.latin.PrevWordsInfo; import com.android.inputmethod.latin.utils.CollectionUtils; import java.util.ArrayList; @@ -57,7 +58,7 @@ public final class AndroidSpellCheckerSession extends AndroidWordLevelSpellCheck final int offset = ssi.getOffsetAt(i); final int length = ssi.getLengthAt(i); final String subText = typedText.substring(offset, offset + length); - final String prevWord = currentWord; + final PrevWordsInfo prevWordsInfo = new PrevWordsInfo(currentWord); currentWord = subText; if (!subText.contains(AndroidSpellCheckerService.SINGLE_QUOTE)) { continue; @@ -73,7 +74,7 @@ public final class AndroidSpellCheckerSession extends AndroidWordLevelSpellCheck if (TextUtils.isEmpty(splitText)) { continue; } - if (mSuggestionsCache.getSuggestionsFromCache(splitText, prevWord) == null) { + if (mSuggestionsCache.getSuggestionsFromCache(splitText, prevWordsInfo) == null) { continue; } final int newLength = splitText.length(); @@ -148,7 +149,8 @@ public final class AndroidSpellCheckerSession extends AndroidWordLevelSpellCheck } else { prevWord = null; } - retval[i] = onGetSuggestionsInternal(textInfos[i], prevWord, suggestionsLimit); + final PrevWordsInfo prevWordsInfo = new PrevWordsInfo(prevWord); + retval[i] = onGetSuggestionsInternal(textInfos[i], prevWordsInfo, suggestionsLimit); retval[i].setCookieAndSequence(textInfos[i].getCookie(), textInfos[i].getSequence()); } diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java index 69d092751..cf26000d5 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java @@ -31,6 +31,7 @@ import com.android.inputmethod.compat.SuggestionsInfoCompatUtils; import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.Dictionary; +import com.android.inputmethod.latin.PrevWordsInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.WordComposer; import com.android.inputmethod.latin.spellcheck.AndroidSpellCheckerService.SuggestionsGatherer; @@ -71,26 +72,26 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session { new LruCache<String, SuggestionsParams>(MAX_CACHE_SIZE); // TODO: Support n-gram input - private static String generateKey(String query, String prevWord) { - if (TextUtils.isEmpty(query) || TextUtils.isEmpty(prevWord)) { + private static String generateKey(final String query, final PrevWordsInfo prevWordsInfo) { + if (TextUtils.isEmpty(query) || TextUtils.isEmpty(prevWordsInfo.mPrevWord)) { return query; } - return query + CHAR_DELIMITER + prevWord; + return query + CHAR_DELIMITER + prevWordsInfo.mPrevWord; } - // TODO: Support n-gram input - public SuggestionsParams getSuggestionsFromCache(String query, String prevWord) { - return mUnigramSuggestionsInfoCache.get(generateKey(query, prevWord)); + public SuggestionsParams getSuggestionsFromCache(String query, + final PrevWordsInfo prevWordsInfo) { + return mUnigramSuggestionsInfoCache.get(generateKey(query, prevWordsInfo)); } - // TODO: Support n-gram input public void putSuggestionsToCache( - String query, String prevWord, String[] suggestions, int flags) { + final String query, final PrevWordsInfo prevWordsInfo, + final String[] suggestions, final int flags) { if (suggestions == null || TextUtils.isEmpty(query)) { return; } mUnigramSuggestionsInfoCache.put( - generateKey(query, prevWord), new SuggestionsParams(suggestions, flags)); + generateKey(query, prevWordsInfo), new SuggestionsParams(suggestions, flags)); } public void clearCache() { @@ -259,11 +260,12 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session { } protected SuggestionsInfo onGetSuggestionsInternal( - final TextInfo textInfo, final String prevWord, final int suggestionsLimit) { + final TextInfo textInfo, final PrevWordsInfo prevWordsInfo, + final int suggestionsLimit) { try { final String inText = textInfo.getText(); final SuggestionsParams cachedSuggestionsParams = - mSuggestionsCache.getSuggestionsFromCache(inText, prevWord); + mSuggestionsCache.getSuggestionsFromCache(inText, prevWordsInfo); if (cachedSuggestionsParams != null) { if (DBG) { Log.d(TAG, "Cache hit: " + inText + ", " + cachedSuggestionsParams.mFlags); @@ -325,9 +327,9 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session { composer.setComposingWord(codePoints, coordinates, null /* previousWord */); // TODO: make a spell checker option to block offensive words or not final ArrayList<SuggestedWordInfo> suggestions = - dictInfo.mDictionary.getSuggestions(composer, prevWord, + dictInfo.mDictionary.getSuggestions(composer, prevWordsInfo, dictInfo.getProximityInfo(), true /* blockOffensiveWords */, - null /* additionalFeaturesOptions */, + null /* additionalFeaturesOptions */, 0 /* sessionId */, null /* inOutLanguageWeight */); if (suggestions != null) { for (final SuggestedWordInfo suggestion : suggestions) { @@ -369,7 +371,8 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session { .getValueOf_RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS() : 0); final SuggestionsInfo retval = new SuggestionsInfo(flags, result.mSuggestions); - mSuggestionsCache.putSuggestionsToCache(text, prevWord, result.mSuggestions, flags); + mSuggestionsCache.putSuggestionsToCache(text, prevWordsInfo, result.mSuggestions, + flags); return retval; } catch (RuntimeException e) { // Don't kill the keyboard if there is a bug in the spell checker diff --git a/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java b/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java index c99264347..ba2e0c309 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java @@ -20,6 +20,7 @@ import android.util.Log; import com.android.inputmethod.keyboard.ProximityInfo; import com.android.inputmethod.latin.Dictionary; +import com.android.inputmethod.latin.PrevWordsInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.WordComposer; import com.android.inputmethod.latin.utils.CollectionUtils; @@ -52,9 +53,9 @@ public final class DictionaryPool extends LinkedBlockingQueue<DictAndKeyboard> { // TODO: this dummy dictionary should be a singleton in the Dictionary class. @Override public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, - final String prevWord, final ProximityInfo proximityInfo, + final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, - final float[] inOutLanguageWeight) { + final int sessionId, final float[] inOutLanguageWeight) { return noSuggestions; } @Override diff --git a/java/src/com/android/inputmethod/latin/spellcheck/SynchronouslyLoadedContactsBinaryDictionary.java b/java/src/com/android/inputmethod/latin/spellcheck/SynchronouslyLoadedContactsBinaryDictionary.java index a694bf47d..75075664f 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/SynchronouslyLoadedContactsBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/SynchronouslyLoadedContactsBinaryDictionary.java @@ -20,6 +20,7 @@ import android.content.Context; import com.android.inputmethod.keyboard.ProximityInfo; import com.android.inputmethod.latin.ContactsBinaryDictionary; +import com.android.inputmethod.latin.PrevWordsInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.WordComposer; @@ -36,12 +37,12 @@ public final class SynchronouslyLoadedContactsBinaryDictionary extends ContactsB @Override public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer codes, - final String prevWordForBigrams, final ProximityInfo proximityInfo, + final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, - final float[] inOutLanguageWeight) { + final int sessionId, final float[] inOutLanguageWeight) { synchronized (mLock) { - return super.getSuggestions(codes, prevWordForBigrams, proximityInfo, - blockOffensiveWords, additionalFeaturesOptions, inOutLanguageWeight); + return super.getSuggestions(codes, prevWordsInfo, proximityInfo, + blockOffensiveWords, additionalFeaturesOptions, sessionId, inOutLanguageWeight); } } diff --git a/java/src/com/android/inputmethod/latin/spellcheck/SynchronouslyLoadedUserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/spellcheck/SynchronouslyLoadedUserBinaryDictionary.java index 1a6dd5818..f2d981a9d 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/SynchronouslyLoadedUserBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/SynchronouslyLoadedUserBinaryDictionary.java @@ -19,6 +19,7 @@ package com.android.inputmethod.latin.spellcheck; import android.content.Context; import com.android.inputmethod.keyboard.ProximityInfo; +import com.android.inputmethod.latin.PrevWordsInfo; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; import com.android.inputmethod.latin.UserBinaryDictionary; import com.android.inputmethod.latin.WordComposer; @@ -41,12 +42,12 @@ public final class SynchronouslyLoadedUserBinaryDictionary extends UserBinaryDic @Override public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer codes, - final String prevWordForBigrams, final ProximityInfo proximityInfo, + final PrevWordsInfo prevWordsInfo, final ProximityInfo proximityInfo, final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, - final float[] inOutLanguageWeight) { + final int sessionId, final float[] inOutLanguageWeight) { synchronized (mLock) { - return super.getSuggestions(codes, prevWordForBigrams, proximityInfo, - blockOffensiveWords, additionalFeaturesOptions, inOutLanguageWeight); + return super.getSuggestions(codes, prevWordsInfo, proximityInfo, + blockOffensiveWords, additionalFeaturesOptions, sessionId, inOutLanguageWeight); } } diff --git a/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java b/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java index 0a0379982..a21953259 100644 --- a/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java +++ b/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java @@ -16,8 +16,15 @@ package com.android.inputmethod.latin.utils; +import java.util.Locale; +import java.util.concurrent.TimeUnit; + +import android.content.Context; +import android.util.Log; + import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.latin.Constants; +import com.android.inputmethod.latin.PrevWordsInfo; import com.android.inputmethod.latin.Suggest; import com.android.inputmethod.latin.Suggest.OnGetSuggestedWordsCallback; import com.android.inputmethod.latin.SuggestedWords; @@ -29,6 +36,11 @@ import com.android.inputmethod.latin.WordComposer; * or user history dictionaries */ public class DistracterFilter { + private static final String TAG = DistracterFilter.class.getSimpleName(); + + private static final long TIMEOUT_TO_WAIT_LOADING_DICTIONARIES_IN_SECONDS = 120; + + private final Context mContext; private final Suggest mSuggest; private final Keyboard mKeyboard; @@ -42,13 +54,13 @@ public class DistracterFilter { /** * Create a DistracterFilter instance. * - * @param suggest an instance of Suggest which will be used to obtain a list of suggestions - * for a potential distracter + * @param context the context. * @param keyboard the keyboard that is currently being used. This information is needed * when calling mSuggest.getSuggestedWords(...) to obtain a list of suggestions. */ - public DistracterFilter(final Suggest suggest, final Keyboard keyboard) { - mSuggest = suggest; + public DistracterFilter(final Context context, final Keyboard keyboard) { + mContext = context; + mSuggest = new Suggest(); mKeyboard = keyboard; } @@ -66,29 +78,48 @@ public class DistracterFilter { return false; } + private void loadDictionariesForLocale(final Locale newlocale) throws InterruptedException { + mSuggest.mDictionaryFacilitator.resetDictionaries(mContext, newlocale, + false /* useContactsDict */, false /* usePersonalizedDicts */, + false /* forceReloadMainDictionary */, null /* listener */); + mSuggest.mDictionaryFacilitator.waitForLoadingMainDictionary( + TIMEOUT_TO_WAIT_LOADING_DICTIONARIES_IN_SECONDS, TimeUnit.SECONDS); + } + /** * Determine whether a word is a distracter to words in dictionaries. * - * @param prevWord the previous word, or null if none. + * @param prevWordsInfo the information of previous words. * @param testedWord the word that will be tested to see whether it is a distracter to words * in dictionaries. + * @param locale the locale of words. * @return true if testedWord is a distracter, otherwise false. */ - public boolean isDistracterToWordsInDictionaries(final String prevWord, - final String testedWord) { - if (mSuggest == null || mKeyboard == null) { + public boolean isDistracterToWordsInDictionaries(final PrevWordsInfo prevWordsInfo, + final String testedWord, final Locale locale) { + if (mKeyboard == null || locale == null) { return false; } + if (!locale.equals(mSuggest.mDictionaryFacilitator.getLocale())) { + // Reset dictionaries for the locale. + try { + loadDictionariesForLocale(locale); + } catch (final InterruptedException e) { + Log.e(TAG, "Interrupted while waiting for loading dicts in DistracterFilter", e); + return false; + } + } final WordComposer composer = new WordComposer(); final int[] codePoints = StringUtils.toCodePointArray(testedWord); final int[] coordinates; coordinates = mKeyboard.getCoordinates(codePoints); - composer.setComposingWord(codePoints, coordinates, prevWord); + composer.setComposingWord(codePoints, coordinates, prevWordsInfo.mPrevWord); - final int trailingSingleQuotesCount = composer.trailingSingleQuotesCount(); - final String consideredWord = trailingSingleQuotesCount > 0 ? testedWord.substring(0, - testedWord.length() - trailingSingleQuotesCount) : testedWord; + final int trailingSingleQuotesCount = StringUtils.getTrailingSingleQuotesCount(testedWord); + final String consideredWord = trailingSingleQuotesCount > 0 ? + testedWord.substring(0, testedWord.length() - trailingSingleQuotesCount) : + testedWord; final AsyncResultHolder<Boolean> holder = new AsyncResultHolder<Boolean>(); final OnGetSuggestedWordsCallback callback = new OnGetSuggestedWordsCallback() { @Override @@ -103,7 +134,7 @@ public class DistracterFilter { } } }; - mSuggest.getSuggestedWords(composer, prevWord, mKeyboard.getProximityInfo(), + mSuggest.getSuggestedWords(composer, prevWordsInfo, mKeyboard.getProximityInfo(), true /* blockOffensiveWords */, true /* isCorrectionEnbaled */, null /* additionalFeaturesOptions */, 0 /* sessionId */, SuggestedWords.NOT_A_SEQUENCE_NUMBER, callback); diff --git a/java/src/com/android/inputmethod/latin/utils/DistracterFilterUtils.java b/java/src/com/android/inputmethod/latin/utils/DistracterFilterUtils.java index df07f976c..8a711a24e 100644 --- a/java/src/com/android/inputmethod/latin/utils/DistracterFilterUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/DistracterFilterUtils.java @@ -16,17 +16,18 @@ package com.android.inputmethod.latin.utils; +import android.content.Context; + import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.KeyboardSwitcher; import com.android.inputmethod.keyboard.MainKeyboardView; -import com.android.inputmethod.latin.Suggest; public class DistracterFilterUtils { private DistracterFilterUtils() { // This utility class is not publicly instantiable. } - public static final DistracterFilter createDistracterFilter(final Suggest suggest, + public static final DistracterFilter createDistracterFilter(final Context context, final KeyboardSwitcher keyboardSwitcher) { final MainKeyboardView mainKeyboardView = keyboardSwitcher.getMainKeyboardView(); // TODO: Create Keyboard when mainKeyboardView is null. @@ -34,7 +35,7 @@ public class DistracterFilterUtils { // spellchecker's logic. final Keyboard keyboard = (mainKeyboardView != null) ? mainKeyboardView.getKeyboard() : null; - final DistracterFilter distracterFilter = new DistracterFilter(suggest, keyboard); + final DistracterFilter distracterFilter = new DistracterFilter(context, keyboard); return distracterFilter; } } diff --git a/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java b/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java index 74e7db901..aaf4a4064 100644 --- a/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java +++ b/java/src/com/android/inputmethod/latin/utils/LanguageModelParam.java @@ -20,6 +20,7 @@ import android.util.Log; import com.android.inputmethod.latin.Dictionary; import com.android.inputmethod.latin.DictionaryFacilitatorForSuggest; +import com.android.inputmethod.latin.PrevWordsInfo; import com.android.inputmethod.latin.settings.SpacingAndPunctuations; import java.util.ArrayList; @@ -85,7 +86,7 @@ public final class LanguageModelParam { final ArrayList<LanguageModelParam> languageModelParams = CollectionUtils.newArrayList(); final int N = tokens.size(); - String prevWord = null; + PrevWordsInfo prevWordsInfo = new PrevWordsInfo(null); for (int i = 0; i < N; ++i) { final String tempWord = tokens.get(i); if (StringUtils.isEmptyStringOrWhiteSpaces(tempWord)) { @@ -102,7 +103,7 @@ public final class LanguageModelParam { + tempWord + "\""); } // Sentence terminator found. Split. - prevWord = null; + prevWordsInfo = new PrevWordsInfo(null); continue; } if (DEBUG_TOKEN) { @@ -110,19 +111,19 @@ public final class LanguageModelParam { } final LanguageModelParam languageModelParam = detectWhetherVaildWordOrNotAndGetLanguageModelParam( - prevWord, tempWord, timestamp, dictionaryFacilitator, + prevWordsInfo, tempWord, timestamp, dictionaryFacilitator, distracterFilter); if (languageModelParam == null) { continue; } languageModelParams.add(languageModelParam); - prevWord = languageModelParam.mTargetWord; + prevWordsInfo = new PrevWordsInfo(languageModelParam.mTargetWord); } return languageModelParams; } private static LanguageModelParam detectWhetherVaildWordOrNotAndGetLanguageModelParam( - final String prevWord, final String targetWord, final int timestamp, + final PrevWordsInfo prevWordsInfo, final String targetWord, final int timestamp, final DictionaryFacilitatorForSuggest dictionaryFacilitator, final DistracterFilter distracterFilter) { final Locale locale = dictionaryFacilitator.getLocale(); @@ -133,14 +134,14 @@ public final class LanguageModelParam { // distracterFilter in the following code. If targetWord is a distracter, // it should be filtered out. if (dictionaryFacilitator.isValidWord(targetWord, false /* ignoreCase */)) { - return createAndGetLanguageModelParamOfWord(prevWord, targetWord, timestamp, + return createAndGetLanguageModelParamOfWord(prevWordsInfo, targetWord, timestamp, true /* isValidWord */, locale); } final String lowerCaseTargetWord = targetWord.toLowerCase(locale); if (dictionaryFacilitator.isValidWord(lowerCaseTargetWord, false /* ignoreCase */)) { // Add the lower-cased word. - return createAndGetLanguageModelParamOfWord(prevWord, lowerCaseTargetWord, + return createAndGetLanguageModelParamOfWord(prevWordsInfo, lowerCaseTargetWord, timestamp, true /* isValidWord */, locale); } @@ -150,26 +151,26 @@ public final class LanguageModelParam { // Adding such a word to dictonaries would interfere with entering in-dictionary words. For // example, adding "mot" to dictionaries might interfere with entering "not". // This kind of OOV should be filtered out. - if (distracterFilter.isDistracterToWordsInDictionaries(prevWord, targetWord)) { + if (distracterFilter.isDistracterToWordsInDictionaries(prevWordsInfo, targetWord, locale)) { return null; } - return createAndGetLanguageModelParamOfWord(prevWord, targetWord, timestamp, + return createAndGetLanguageModelParamOfWord(prevWordsInfo, targetWord, timestamp, false /* isValidWord */, locale); } private static LanguageModelParam createAndGetLanguageModelParamOfWord( - final String prevWord, final String targetWord, final int timestamp, + final PrevWordsInfo prevWordsInfo, final String targetWord, final int timestamp, final boolean isValidWord, final Locale locale) { final String word; if (StringUtils.getCapitalizationType(targetWord) == StringUtils.CAPITALIZE_FIRST - && prevWord == null && !isValidWord) { + && prevWordsInfo.mPrevWord == null && !isValidWord) { word = targetWord.toLowerCase(locale); } else { word = targetWord; } final int unigramProbability = isValidWord ? UNIGRAM_PROBABILITY_FOR_VALID_WORD : UNIGRAM_PROBABILITY_FOR_OOV_WORD; - if (prevWord == null) { + if (prevWordsInfo.mPrevWord == null) { if (DEBUG) { Log.d(TAG, "--- add unigram: current(" + (isValidWord ? "Valid" : "OOV") + ") = " + word); @@ -177,12 +178,12 @@ public final class LanguageModelParam { return new LanguageModelParam(word, unigramProbability, timestamp); } if (DEBUG) { - Log.d(TAG, "--- add bigram: prev = " + prevWord + ", current(" + Log.d(TAG, "--- add bigram: prev = " + prevWordsInfo.mPrevWord + ", current(" + (isValidWord ? "Valid" : "OOV") + ") = " + word); } final int bigramProbability = isValidWord ? BIGRAM_PROBABILITY_FOR_VALID_WORD : BIGRAM_PROBABILITY_FOR_OOV_WORD; - return new LanguageModelParam(prevWord, word, unigramProbability, + return new LanguageModelParam(prevWordsInfo.mPrevWord, word, unigramProbability, bigramProbability, timestamp); } } diff --git a/java/src/com/android/inputmethod/latin/utils/StringUtils.java b/java/src/com/android/inputmethod/latin/utils/StringUtils.java index 374badc19..73ac9a573 100644 --- a/java/src/com/android/inputmethod/latin/utils/StringUtils.java +++ b/java/src/com/android/inputmethod/latin/utils/StringUtils.java @@ -538,6 +538,15 @@ public final class StringUtils { ? casedText.codePointAt(0) : CODE_UNSPECIFIED; } + public static int getTrailingSingleQuotesCount(final CharSequence charSequence) { + final int lastIndex = charSequence.length() - 1; + int i = lastIndex; + while (i >= 0 && charSequence.charAt(i) == Constants.CODE_SINGLE_QUOTE) { + --i; + } + return lastIndex - i; + } + @UsedForTesting public static class Stringizer<E> { public String stringize(final E element) { |