Loading common/src/com/android/inputmethod/latin/common/Constants.java +4 −0 Original line number Diff line number Diff line Loading @@ -325,6 +325,10 @@ public final class Constants { public static final int DECODER_SCORE_SCALAR = 1000000; public static final int DECODER_MAX_SCORE = 1000000000; public static final int EVENT_BACKSPACE = 1; public static final int EVENT_REJECTION = 2; public static final int EVENT_REVERT = 3; private Constants() { // This utility class is not publicly instantiable. } Loading java/src/com/android/inputmethod/latin/DictionaryFacilitator.java +3 −1 Original line number Diff line number Diff line Loading @@ -150,7 +150,9 @@ public interface DictionaryFacilitator { @Nonnull final NgramContext ngramContext, final int timeStampInSeconds, final boolean blockPotentiallyOffensive); void removeWordFromPersonalizedDicts(final String word); void unlearnFromUserHistory(final String word, @Nonnull final NgramContext ngramContext, final int timeStampInSeconds, final int eventType); // TODO: Revise the way to fusion suggestion results. SuggestionResults getSuggestionResults(final WordComposer composer, Loading java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java +8 −2 Original line number Diff line number Diff line Loading @@ -654,9 +654,15 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { } } public void removeWordFromPersonalizedDicts(final String word) { @Override public void unlearnFromUserHistory(final String word, @Nonnull final NgramContext ngramContext, final int timeStampInSeconds, final int eventType) { // TODO: Decide whether or not to remove the word on EVENT_BACKSPACE. if (eventType != Constants.EVENT_BACKSPACE) { removeWord(Dictionary.TYPE_USER_HISTORY, word); } } // TODO: Revise the way to fusion suggestion results. @Override Loading java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java +53 −2 Original line number Diff line number Diff line Loading @@ -1007,7 +1007,8 @@ public final class InputLogic { mWordComposer.reset(); mWordComposer.setRejectedBatchModeSuggestion(rejectedSuggestion); if (!TextUtils.isEmpty(rejectedSuggestion)) { mDictionaryFacilitator.removeWordFromPersonalizedDicts(rejectedSuggestion); unlearnWord(rejectedSuggestion, inputTransaction.mSettingsValues, Constants.EVENT_REJECTION); } StatsUtils.onBackspaceWordDelete(rejectedSuggestion.length()); } else { Loading Loading @@ -1060,6 +1061,8 @@ public final class InputLogic { } } boolean hasUnlearnedWordBeingDeleted = false; // No cancelling of commit/double space/swap: we have a regular backspace. // We should backspace one char and restart suggestion if at the end of a word. if (mConnection.hasSelection()) { Loading Loading @@ -1090,6 +1093,11 @@ public final class InputLogic { sendDownUpKeyEvent(KeyEvent.KEYCODE_DEL); int totalDeletedLength = 1; if (mDeleteCount > Constants.DELETE_ACCELERATE_AT) { // If this is an accelerated (i.e., double) deletion, then we need to // consider unlearning here too because we may have just entered the // previous word, and the next deletion will currupt it. hasUnlearnedWordBeingDeleted |= unlearnWordBeingDeleted( inputTransaction.mSettingsValues, currentKeyboardScriptId); sendDownUpKeyEvent(KeyEvent.KEYCODE_DEL); totalDeletedLength++; } Loading @@ -1112,6 +1120,11 @@ public final class InputLogic { mConnection.deleteSurroundingText(lengthToDelete, 0); int totalDeletedLength = lengthToDelete; if (mDeleteCount > Constants.DELETE_ACCELERATE_AT) { // If this is an accelerated (i.e., double) deletion, then we need to // consider unlearning here too because we may have just entered the // previous word, and the next deletion will currupt it. hasUnlearnedWordBeingDeleted |= unlearnWordBeingDeleted( inputTransaction.mSettingsValues, currentKeyboardScriptId); final int codePointBeforeCursorToDeleteAgain = mConnection.getCodePointBeforeCursor(); if (codePointBeforeCursorToDeleteAgain != Constants.NOT_A_CODE) { Loading @@ -1124,6 +1137,11 @@ public final class InputLogic { StatsUtils.onBackspacePressed(totalDeletedLength); } } if (!hasUnlearnedWordBeingDeleted) { // Consider unlearning the word being deleted (if we have not done so already). unlearnWordBeingDeleted( inputTransaction.mSettingsValues, currentKeyboardScriptId); } if (inputTransaction.mSettingsValues.isSuggestionsEnabledPerUserSettings() && inputTransaction.mSettingsValues.mSpacingAndPunctuations .mCurrentLanguageHasSpaces Loading @@ -1135,6 +1153,38 @@ public final class InputLogic { } } boolean unlearnWordBeingDeleted( final SettingsValues settingsValues,final int currentKeyboardScriptId) { // If we just started backspacing to delete a previous word (but have not // entered the composing state yet), unlearn the word. // TODO: Consider tracking whether or not this word was typed by the user. if (!mConnection.hasSelection() && settingsValues.isSuggestionsEnabledPerUserSettings() && settingsValues.mSpacingAndPunctuations.mCurrentLanguageHasSpaces && !mConnection.isCursorFollowedByWordCharacter( settingsValues.mSpacingAndPunctuations)) { final TextRange range = mConnection.getWordRangeAtCursor( settingsValues.mSpacingAndPunctuations, currentKeyboardScriptId); final String wordBeingDeleted = range.mWord.toString(); if (!wordBeingDeleted.isEmpty()) { unlearnWord(wordBeingDeleted, settingsValues, Constants.EVENT_BACKSPACE); return true; } } return false; } void unlearnWord(final String word, final SettingsValues settingsValues, final int eventType) { final NgramContext ngramContext = mConnection.getNgramContextFromNthPreviousWord( settingsValues.mSpacingAndPunctuations, 2); final int timeStampInSeconds = (int)TimeUnit.MILLISECONDS.toSeconds( System.currentTimeMillis()); mDictionaryFacilitator.unlearnFromUserHistory( word, ngramContext, timeStampInSeconds, eventType); } /** * Handle a press on the language switch key (the "globe key") */ Loading Loading @@ -1546,7 +1596,8 @@ public final class InputLogic { } mConnection.deleteSurroundingText(deleteLength, 0); if (!TextUtils.isEmpty(committedWord)) { mDictionaryFacilitator.removeWordFromPersonalizedDicts(committedWordString); unlearnWord(committedWordString, inputTransaction.mSettingsValues, Constants.EVENT_REVERT); } final String stringToCommit = originallyTypedWord + (usePhantomSpace ? "" : separatorString); Loading Loading
common/src/com/android/inputmethod/latin/common/Constants.java +4 −0 Original line number Diff line number Diff line Loading @@ -325,6 +325,10 @@ public final class Constants { public static final int DECODER_SCORE_SCALAR = 1000000; public static final int DECODER_MAX_SCORE = 1000000000; public static final int EVENT_BACKSPACE = 1; public static final int EVENT_REJECTION = 2; public static final int EVENT_REVERT = 3; private Constants() { // This utility class is not publicly instantiable. } Loading
java/src/com/android/inputmethod/latin/DictionaryFacilitator.java +3 −1 Original line number Diff line number Diff line Loading @@ -150,7 +150,9 @@ public interface DictionaryFacilitator { @Nonnull final NgramContext ngramContext, final int timeStampInSeconds, final boolean blockPotentiallyOffensive); void removeWordFromPersonalizedDicts(final String word); void unlearnFromUserHistory(final String word, @Nonnull final NgramContext ngramContext, final int timeStampInSeconds, final int eventType); // TODO: Revise the way to fusion suggestion results. SuggestionResults getSuggestionResults(final WordComposer composer, Loading
java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java +8 −2 Original line number Diff line number Diff line Loading @@ -654,9 +654,15 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator { } } public void removeWordFromPersonalizedDicts(final String word) { @Override public void unlearnFromUserHistory(final String word, @Nonnull final NgramContext ngramContext, final int timeStampInSeconds, final int eventType) { // TODO: Decide whether or not to remove the word on EVENT_BACKSPACE. if (eventType != Constants.EVENT_BACKSPACE) { removeWord(Dictionary.TYPE_USER_HISTORY, word); } } // TODO: Revise the way to fusion suggestion results. @Override Loading
java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java +53 −2 Original line number Diff line number Diff line Loading @@ -1007,7 +1007,8 @@ public final class InputLogic { mWordComposer.reset(); mWordComposer.setRejectedBatchModeSuggestion(rejectedSuggestion); if (!TextUtils.isEmpty(rejectedSuggestion)) { mDictionaryFacilitator.removeWordFromPersonalizedDicts(rejectedSuggestion); unlearnWord(rejectedSuggestion, inputTransaction.mSettingsValues, Constants.EVENT_REJECTION); } StatsUtils.onBackspaceWordDelete(rejectedSuggestion.length()); } else { Loading Loading @@ -1060,6 +1061,8 @@ public final class InputLogic { } } boolean hasUnlearnedWordBeingDeleted = false; // No cancelling of commit/double space/swap: we have a regular backspace. // We should backspace one char and restart suggestion if at the end of a word. if (mConnection.hasSelection()) { Loading Loading @@ -1090,6 +1093,11 @@ public final class InputLogic { sendDownUpKeyEvent(KeyEvent.KEYCODE_DEL); int totalDeletedLength = 1; if (mDeleteCount > Constants.DELETE_ACCELERATE_AT) { // If this is an accelerated (i.e., double) deletion, then we need to // consider unlearning here too because we may have just entered the // previous word, and the next deletion will currupt it. hasUnlearnedWordBeingDeleted |= unlearnWordBeingDeleted( inputTransaction.mSettingsValues, currentKeyboardScriptId); sendDownUpKeyEvent(KeyEvent.KEYCODE_DEL); totalDeletedLength++; } Loading @@ -1112,6 +1120,11 @@ public final class InputLogic { mConnection.deleteSurroundingText(lengthToDelete, 0); int totalDeletedLength = lengthToDelete; if (mDeleteCount > Constants.DELETE_ACCELERATE_AT) { // If this is an accelerated (i.e., double) deletion, then we need to // consider unlearning here too because we may have just entered the // previous word, and the next deletion will currupt it. hasUnlearnedWordBeingDeleted |= unlearnWordBeingDeleted( inputTransaction.mSettingsValues, currentKeyboardScriptId); final int codePointBeforeCursorToDeleteAgain = mConnection.getCodePointBeforeCursor(); if (codePointBeforeCursorToDeleteAgain != Constants.NOT_A_CODE) { Loading @@ -1124,6 +1137,11 @@ public final class InputLogic { StatsUtils.onBackspacePressed(totalDeletedLength); } } if (!hasUnlearnedWordBeingDeleted) { // Consider unlearning the word being deleted (if we have not done so already). unlearnWordBeingDeleted( inputTransaction.mSettingsValues, currentKeyboardScriptId); } if (inputTransaction.mSettingsValues.isSuggestionsEnabledPerUserSettings() && inputTransaction.mSettingsValues.mSpacingAndPunctuations .mCurrentLanguageHasSpaces Loading @@ -1135,6 +1153,38 @@ public final class InputLogic { } } boolean unlearnWordBeingDeleted( final SettingsValues settingsValues,final int currentKeyboardScriptId) { // If we just started backspacing to delete a previous word (but have not // entered the composing state yet), unlearn the word. // TODO: Consider tracking whether or not this word was typed by the user. if (!mConnection.hasSelection() && settingsValues.isSuggestionsEnabledPerUserSettings() && settingsValues.mSpacingAndPunctuations.mCurrentLanguageHasSpaces && !mConnection.isCursorFollowedByWordCharacter( settingsValues.mSpacingAndPunctuations)) { final TextRange range = mConnection.getWordRangeAtCursor( settingsValues.mSpacingAndPunctuations, currentKeyboardScriptId); final String wordBeingDeleted = range.mWord.toString(); if (!wordBeingDeleted.isEmpty()) { unlearnWord(wordBeingDeleted, settingsValues, Constants.EVENT_BACKSPACE); return true; } } return false; } void unlearnWord(final String word, final SettingsValues settingsValues, final int eventType) { final NgramContext ngramContext = mConnection.getNgramContextFromNthPreviousWord( settingsValues.mSpacingAndPunctuations, 2); final int timeStampInSeconds = (int)TimeUnit.MILLISECONDS.toSeconds( System.currentTimeMillis()); mDictionaryFacilitator.unlearnFromUserHistory( word, ngramContext, timeStampInSeconds, eventType); } /** * Handle a press on the language switch key (the "globe key") */ Loading Loading @@ -1546,7 +1596,8 @@ public final class InputLogic { } mConnection.deleteSurroundingText(deleteLength, 0); if (!TextUtils.isEmpty(committedWord)) { mDictionaryFacilitator.removeWordFromPersonalizedDicts(committedWordString); unlearnWord(committedWordString, inputTransaction.mSettingsValues, Constants.EVENT_REVERT); } final String stringToCommit = originallyTypedWord + (usePhantomSpace ? "" : separatorString); Loading