[IL17] Move commitChosenWord to InputLogic.

Also not-cache a value whose documentation says not to cache
it. That makes it write only, so remove it.

Bug: 8636060
Change-Id: I39798a039cebf79ad78a41fe457c9d9764a3f275
This commit is contained in:
Jean Chalard 2013-12-19 21:53:08 +09:00
parent a905fcec00
commit 1c0374da49
2 changed files with 89 additions and 84 deletions

View file

@ -151,7 +151,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private final SubtypeSwitcher mSubtypeSwitcher; private final SubtypeSwitcher mSubtypeSwitcher;
private final SubtypeState mSubtypeState = new SubtypeState(); private final SubtypeState mSubtypeState = new SubtypeState();
private boolean mIsMainDictionaryAvailable;
private UserBinaryDictionary mUserDictionary; private UserBinaryDictionary mUserDictionary;
private boolean mIsUserDictionaryAvailable; private boolean mIsUserDictionaryAvailable;
@ -555,7 +554,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// Note that this method is called from a non-UI thread. // Note that this method is called from a non-UI thread.
@Override @Override
public void onUpdateMainDictionaryAvailability(final boolean isMainDictionaryAvailable) { public void onUpdateMainDictionaryAvailability(final boolean isMainDictionaryAvailable) {
mIsMainDictionaryAvailable = isMainDictionaryAvailable;
final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView(); final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
if (mainKeyboardView != null) { if (mainKeyboardView != null) {
mainKeyboardView.setMainDictionaryAvailability(isMainDictionaryAvailable); mainKeyboardView.setMainDictionaryAvailability(isMainDictionaryAvailable);
@ -586,7 +584,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
newSuggest.setAutoCorrectionThreshold(settingsValues.mAutoCorrectionThreshold); newSuggest.setAutoCorrectionThreshold(settingsValues.mAutoCorrectionThreshold);
} }
mIsMainDictionaryAvailable = DictionaryFactory.isDictionaryAvailable(this, subtypeLocale);
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) { if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
ResearchLogger.getInstance().initSuggest(newSuggest); ResearchLogger.getInstance().initSuggest(newSuggest);
} }
@ -605,7 +602,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final Locale subtypeLocale = mSubtypeSwitcher.getCurrentSubtypeLocale(); final Locale subtypeLocale = mSubtypeSwitcher.getCurrentSubtypeLocale();
mInputLogic.mSuggest.resetMainDict(this, subtypeLocale, mInputLogic.mSuggest.resetMainDict(this, subtypeLocale,
this /* SuggestInitializationListener */); this /* SuggestInitializationListener */);
mIsMainDictionaryAvailable = DictionaryFactory.isDictionaryAvailable(this, subtypeLocale);
} }
@Override @Override
@ -637,7 +633,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mDisplayOrientation = conf.orientation; mDisplayOrientation = conf.orientation;
mHandler.startOrientationChanging(); mHandler.startOrientationChanging();
mInputLogic.mConnection.beginBatchEdit(); mInputLogic.mConnection.beginBatchEdit();
mInputLogic.commitTyped(LastComposedWord.NOT_A_SEPARATOR); mInputLogic.commitTyped(mSettings.getCurrent(), LastComposedWord.NOT_A_SEPARATOR);
mInputLogic.mConnection.finishComposingText(); mInputLogic.mConnection.finishComposingText();
mInputLogic.mConnection.endBatchEdit(); mInputLogic.mConnection.endBatchEdit();
if (isShowingOptionDialog()) { if (isShowingOptionDialog()) {
@ -858,7 +854,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mHandler.cancelUpdateSuggestionStrip(); mHandler.cancelUpdateSuggestionStrip();
mHandler.cancelDoubleSpacePeriodTimer(); mHandler.cancelDoubleSpacePeriodTimer();
mainKeyboardView.setMainDictionaryAvailability(mIsMainDictionaryAvailable); mainKeyboardView.setMainDictionaryAvailability(null != suggest
? suggest.hasMainDictionary() : false);
mainKeyboardView.setKeyPreviewPopupEnabled(currentSettingsValues.mKeyPreviewPopupOn, mainKeyboardView.setKeyPreviewPopupEnabled(currentSettingsValues.mKeyPreviewPopupOn,
currentSettingsValues.mKeyPreviewPopupDismissDelay); currentSettingsValues.mKeyPreviewPopupDismissDelay);
mainKeyboardView.setSlidingKeyInputPreviewEnabled( mainKeyboardView.setSlidingKeyInputPreviewEnabled(
@ -1402,7 +1399,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mInputLogic.commitCurrentAutoCorrection(currentSettingsValues, mInputLogic.commitCurrentAutoCorrection(currentSettingsValues,
LastComposedWord.NOT_A_SEPARATOR, mHandler); LastComposedWord.NOT_A_SEPARATOR, mHandler);
} else { } else {
mInputLogic.commitTyped(LastComposedWord.NOT_A_SEPARATOR); mInputLogic.commitTyped(currentSettingsValues, LastComposedWord.NOT_A_SEPARATOR);
} }
} }
final int codePointBeforeCursor = mInputLogic.mConnection.getCodePointBeforeCursor(); final int codePointBeforeCursor = mInputLogic.mConnection.getCodePointBeforeCursor();
@ -1692,7 +1689,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// TODO[IL]: Rename this to avoid using handle* // TODO[IL]: Rename this to avoid using handle*
private void handleClose() { private void handleClose() {
// TODO: Verify that words are logged properly when IME is closed. // TODO: Verify that words are logged properly when IME is closed.
mInputLogic.commitTyped(LastComposedWord.NOT_A_SEPARATOR); mInputLogic.commitTyped(mSettings.getCurrent(), LastComposedWord.NOT_A_SEPARATOR);
requestHideSelf(0); requestHideSelf(0);
final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView(); final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
if (mainKeyboardView != null) { if (mainKeyboardView != null) {
@ -1979,8 +1976,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// typed word. // typed word.
final String replacedWord = mInputLogic.mWordComposer.getTypedWord(); final String replacedWord = mInputLogic.mWordComposer.getTypedWord();
LatinImeLogger.logOnManualSuggestion(replacedWord, suggestion, index, suggestedWords); LatinImeLogger.logOnManualSuggestion(replacedWord, suggestion, index, suggestedWords);
commitChosenWord(suggestion, LastComposedWord.COMMIT_TYPE_MANUAL_PICK, mInputLogic.commitChosenWord(currentSettings, suggestion,
LastComposedWord.NOT_A_SEPARATOR); LastComposedWord.COMMIT_TYPE_MANUAL_PICK, LastComposedWord.NOT_A_SEPARATOR);
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) { if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
ResearchLogger.latinIME_pickSuggestionManually(replacedWord, index, suggestion, ResearchLogger.latinIME_pickSuggestionManually(replacedWord, index, suggestion,
mInputLogic.mWordComposer.isBatchMode(), suggestionInfo.mScore, mInputLogic.mWordComposer.isBatchMode(), suggestionInfo.mScore,
@ -2018,38 +2015,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
} }
} }
/**
* Commits the chosen word to the text field and saves it for later retrieval.
*/
// TODO[IL]: Move to InputLogic and make public again
public void commitChosenWord(final String chosenWord, final int commitType,
final String separatorString) {
final SuggestedWords suggestedWords = mInputLogic.mSuggestedWords;
mInputLogic.mConnection.commitText(SuggestionSpanUtils.getTextWithSuggestionSpan(
this, chosenWord, suggestedWords), 1);
// Add the word to the user history dictionary
final String prevWord = addToUserHistoryDictionary(chosenWord);
// TODO: figure out here if this is an auto-correct or if the best word is actually
// what user typed. Note: currently this is done much later in
// LastComposedWord#didCommitTypedWord by string equality of the remembered
// strings.
mInputLogic.mLastComposedWord = mInputLogic.mWordComposer.commitWord(commitType,
chosenWord, separatorString, prevWord);
final boolean shouldDiscardPreviousWordForSuggestion;
if (0 == StringUtils.codePointCount(separatorString)) {
// Separator is 0-length. Discard the word only if the current language has spaces.
shouldDiscardPreviousWordForSuggestion =
mSettings.getCurrent().mCurrentLanguageHasSpaces;
} else {
// Otherwise, we discard if the separator contains any non-whitespace.
shouldDiscardPreviousWordForSuggestion =
!StringUtils.containsOnlyWhitespace(separatorString);
}
if (shouldDiscardPreviousWordForSuggestion) {
mInputLogic.mWordComposer.discardPreviousWordForSuggestion();
}
}
// TODO[IL]: Define a clean interface for this // TODO[IL]: Define a clean interface for this
public void setPunctuationSuggestions() { public void setPunctuationSuggestions() {
final SettingsValues currentSettings = mSettings.getCurrent(); final SettingsValues currentSettings = mSettings.getCurrent();
@ -2062,38 +2027,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
setSuggestionStripShown(isSuggestionsStripVisible()); setSuggestionStripShown(isSuggestionsStripVisible());
} }
private String addToUserHistoryDictionary(final String suggestion) {
if (TextUtils.isEmpty(suggestion)) return null;
final Suggest suggest = mInputLogic.mSuggest;
if (suggest == null) return null;
// If correction is not enabled, we don't add words to the user history dictionary.
// That's to avoid unintended additions in some sensitive fields, or fields that
// expect to receive non-words.
final SettingsValues currentSettings = mSettings.getCurrent();
if (!currentSettings.mCorrectionEnabled) return null;
final UserHistoryDictionary userHistoryDictionary = suggest.getUserHistoryDictionary();
if (userHistoryDictionary == null) return null;
final String prevWord = mInputLogic.mConnection.getNthPreviousWord(currentSettings, 2);
final String secondWord;
if (mInputLogic.mWordComposer.wasAutoCapitalized()
&& !mInputLogic.mWordComposer.isMostlyCaps()) {
secondWord = suggestion.toLowerCase(mSubtypeSwitcher.getCurrentSubtypeLocale());
} else {
secondWord = suggestion;
}
// We demote unrecognized words (frequency < 0, below) by specifying them as "invalid".
// We don't add words with 0-frequency (assuming they would be profanity etc.).
final int maxFreq = AutoCorrectionUtils.getMaxFrequency(
suggest.getUnigramDictionaries(), suggestion);
if (maxFreq == 0) return null;
userHistoryDictionary.addToDictionary(prevWord, secondWord, maxFreq > 0,
(int)TimeUnit.MILLISECONDS.toSeconds((System.currentTimeMillis())));
return prevWord;
}
private boolean isResumableWord(final String word, final SettingsValues settings) { private boolean isResumableWord(final String word, final SettingsValues settings) {
final int firstCodePoint = word.codePointAt(0); final int firstCodePoint = word.codePointAt(0);
return settings.isWordCodePoint(firstCodePoint) return settings.isWordCodePoint(firstCodePoint)
@ -2356,7 +2289,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
public void launchKeyboardedDialogActivity(final Class<? extends Activity> activityClass) { public void launchKeyboardedDialogActivity(final Class<? extends Activity> activityClass) {
// Put the text in the attached EditText into a safe, saved state before switching to a // Put the text in the attached EditText into a safe, saved state before switching to a
// new activity that will also use the soft keyboard. // new activity that will also use the soft keyboard.
mInputLogic.commitTyped(LastComposedWord.NOT_A_SEPARATOR); mInputLogic.commitTyped(mSettings.getCurrent(), LastComposedWord.NOT_A_SEPARATOR);
launchSubActivity(activityClass); launchSubActivity(activityClass);
} }

View file

@ -39,8 +39,10 @@ import com.android.inputmethod.latin.Suggest;
import com.android.inputmethod.latin.SuggestedWords; import com.android.inputmethod.latin.SuggestedWords;
import com.android.inputmethod.latin.WordComposer; import com.android.inputmethod.latin.WordComposer;
import com.android.inputmethod.latin.define.ProductionFlag; import com.android.inputmethod.latin.define.ProductionFlag;
import com.android.inputmethod.latin.personalization.UserHistoryDictionary;
import com.android.inputmethod.latin.settings.Settings; import com.android.inputmethod.latin.settings.Settings;
import com.android.inputmethod.latin.settings.SettingsValues; import com.android.inputmethod.latin.settings.SettingsValues;
import com.android.inputmethod.latin.utils.AutoCorrectionUtils;
import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.InputTypeUtils; import com.android.inputmethod.latin.utils.InputTypeUtils;
import com.android.inputmethod.latin.utils.LatinImeLoggerUtils; import com.android.inputmethod.latin.utils.LatinImeLoggerUtils;
@ -48,7 +50,9 @@ import com.android.inputmethod.latin.utils.RecapitalizeStatus;
import com.android.inputmethod.latin.utils.StringUtils; import com.android.inputmethod.latin.utils.StringUtils;
import com.android.inputmethod.research.ResearchLogger; import com.android.inputmethod.research.ResearchLogger;
import java.util.Locale;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.concurrent.TimeUnit;
/** /**
* This class manages the input logic. * This class manages the input logic.
@ -284,7 +288,7 @@ public final class InputLogic {
// first so that we can insert the character at the current cursor position. // first so that we can insert the character at the current cursor position.
resetEntireInputState(settingsValues, mLastSelectionStart, mLastSelectionEnd); resetEntireInputState(settingsValues, mLastSelectionStart, mLastSelectionEnd);
} else { } else {
commitTyped(LastComposedWord.NOT_A_SEPARATOR); commitTyped(settingsValues, LastComposedWord.NOT_A_SEPARATOR);
} }
} }
final int keyX, keyY; final int keyX, keyY;
@ -428,7 +432,7 @@ public final class InputLogic {
commitCurrentAutoCorrection(settingsValues, separator, handler); commitCurrentAutoCorrection(settingsValues, separator, handler);
didAutoCorrect = true; didAutoCorrect = true;
} else { } else {
commitTyped(StringUtils.newSingleCodePointString(codePoint)); commitTyped(settingsValues, StringUtils.newSingleCodePointString(codePoint));
} }
} }
@ -811,6 +815,38 @@ public final class InputLogic {
keyboardSwitcher.updateShiftState(); keyboardSwitcher.updateShiftState();
} }
private String performAdditionToUserHistoryDictionary(final SettingsValues settingsValues,
final String suggestion) {
// If correction is not enabled, we don't add words to the user history dictionary.
// That's to avoid unintended additions in some sensitive fields, or fields that
// expect to receive non-words.
if (!settingsValues.mCorrectionEnabled) return null;
if (TextUtils.isEmpty(suggestion)) return null;
final Suggest suggest = mSuggest;
if (suggest == null) return null;
final UserHistoryDictionary userHistoryDictionary = suggest.getUserHistoryDictionary();
if (userHistoryDictionary == null) return null;
final String prevWord = mConnection.getNthPreviousWord(settingsValues, 2);
final String secondWord;
if (mWordComposer.wasAutoCapitalized() && !mWordComposer.isMostlyCaps()) {
secondWord = suggestion.toLowerCase(settingsValues.mLocale);
} else {
secondWord = suggestion;
}
// We demote unrecognized words (frequency < 0, below) by specifying them as "invalid".
// We don't add words with 0-frequency (assuming they would be profanity etc.).
final int maxFreq = AutoCorrectionUtils.getMaxFrequency(
suggest.getUnigramDictionaries(), suggestion);
if (maxFreq == 0) return null;
userHistoryDictionary.addToDictionary(prevWord, secondWord, maxFreq > 0,
(int)TimeUnit.MILLISECONDS.toSeconds((System.currentTimeMillis())));
return prevWord;
}
/** /**
* Check if the cursor is actually at the end of a word. If so, restart suggestions on this * Check if the cursor is actually at the end of a word. If so, restart suggestions on this
* word, otherwise do nothing. * word, otherwise do nothing.
@ -1151,19 +1187,19 @@ public final class InputLogic {
* user presses the Send button for an SMS, we don't auto-correct as that would be unexpected. * user presses the Send button for an SMS, we don't auto-correct as that would be unexpected.
* In this case, `separatorString' is set to NOT_A_SEPARATOR. * In this case, `separatorString' is set to NOT_A_SEPARATOR.
* *
* @param separatorString the separator string that's causing the commit, or NOT_A_SEPARATOR if * @param settingsValues the current values of the settings.
* none. * @param separatorString the separator that's causing the commit, or NOT_A_SEPARATOR if none.
*/ */
// TODO: Make this private // TODO: Make this private
public void commitTyped(final String separatorString) { public void commitTyped(final SettingsValues settingsValues, final String separatorString) {
if (!mWordComposer.isComposingWord()) return; if (!mWordComposer.isComposingWord()) return;
final String typedWord = mWordComposer.getTypedWord(); final String typedWord = mWordComposer.getTypedWord();
if (typedWord.length() > 0) { if (typedWord.length() > 0) {
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) { if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
ResearchLogger.getInstance().onWordFinished(typedWord, mWordComposer.isBatchMode()); ResearchLogger.getInstance().onWordFinished(typedWord, mWordComposer.isBatchMode());
} }
mLatinIME.commitChosenWord(typedWord, LastComposedWord.COMMIT_TYPE_USER_TYPED_WORD, commitChosenWord(settingsValues, typedWord,
separatorString); LastComposedWord.COMMIT_TYPE_USER_TYPED_WORD, separatorString);
} }
} }
@ -1210,8 +1246,8 @@ public final class InputLogic {
ResearchLogger.latinIme_commitCurrentAutoCorrection(typedWord, autoCorrection, ResearchLogger.latinIme_commitCurrentAutoCorrection(typedWord, autoCorrection,
separator, mWordComposer.isBatchMode(), suggestedWords); separator, mWordComposer.isBatchMode(), suggestedWords);
} }
mLatinIME.commitChosenWord(autoCorrection, LastComposedWord.COMMIT_TYPE_DECIDED_WORD, commitChosenWord(settingsValues, autoCorrection,
separator); LastComposedWord.COMMIT_TYPE_DECIDED_WORD, separator);
if (!typedWord.equals(autoCorrection)) { if (!typedWord.equals(autoCorrection)) {
// This will make the correction flash for a short while as a visual clue // This will make the correction flash for a short while as a visual clue
// to the user that auto-correction happened. It has no other effect; in particular // to the user that auto-correction happened. It has no other effect; in particular
@ -1225,4 +1261,40 @@ public final class InputLogic {
} }
} }
} }
/**
* Commits the chosen word to the text field and saves it for later retrieval.
*
* @param settingsValues the current values of the settings.
* @param chosenWord the word we want to commit.
* @param commitType the type of the commit, as one of LastComposedWord.COMMIT_TYPE_*
* @param separatorString the separator that's causing the commit, or NOT_A_SEPARATOR if none.
*/
// TODO: Make this private
public void commitChosenWord(final SettingsValues settingsValues, final String chosenWord,
final int commitType, final String separatorString) {
final SuggestedWords suggestedWords = mSuggestedWords;
mConnection.commitText(SuggestionSpanUtils.getTextWithSuggestionSpan(mLatinIME, chosenWord,
suggestedWords), 1);
// Add the word to the user history dictionary
final String prevWord = performAdditionToUserHistoryDictionary(settingsValues, chosenWord);
// TODO: figure out here if this is an auto-correct or if the best word is actually
// what user typed. Note: currently this is done much later in
// LastComposedWord#didCommitTypedWord by string equality of the remembered
// strings.
mLastComposedWord = mWordComposer.commitWord(commitType,
chosenWord, separatorString, prevWord);
final boolean shouldDiscardPreviousWordForSuggestion;
if (0 == StringUtils.codePointCount(separatorString)) {
// Separator is 0-length. Discard the word only if the current language has spaces.
shouldDiscardPreviousWordForSuggestion = settingsValues.mCurrentLanguageHasSpaces;
} else {
// Otherwise, we discard if the separator contains any non-whitespace.
shouldDiscardPreviousWordForSuggestion =
!StringUtils.containsOnlyWhitespace(separatorString);
}
if (shouldDiscardPreviousWordForSuggestion) {
mWordComposer.discardPreviousWordForSuggestion();
}
}
} }