From e79b1a83126b41e09a8ec0a8dbb751ae0e02c7f6 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Mon, 5 Mar 2012 22:08:16 +0900 Subject: [PATCH] Make SuggestedWords immutable completely Change-Id: I1b0f7b857e89307c987187c1969a2846aa97fdcc --- .../android/inputmethod/latin/LatinIME.java | 7 +- .../inputmethod/latin/SuggestedWords.java | 52 ++++++++----- .../com/android/inputmethod/latin/Utils.java | 20 +++-- .../latin/suggestions/SuggestionsView.java | 75 ++++++++++--------- 4 files changed, 88 insertions(+), 66 deletions(-) diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index f2ba7e0bb..64b9f3364 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -1827,9 +1827,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar builder.addTypedWordAndPreviousSuggestions(typedWord, previousSuggestions); } } - final SuggestedWords suggestedWords = builder.build(); - if (Utils.shouldBlockAutoCorrectionBySafetyNet(suggestedWords, mSuggest)) { - suggestedWords.setShouldBlockAutoCorrectionBySafetyNet(); + if (Utils.shouldBlockAutoCorrectionBySafetyNet(builder, mSuggest)) { + builder.setShouldBlockAutoCorrectionBySafetyNet(); } showSuggestions(builder.build(), typedWord); } @@ -1837,7 +1836,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar public void showSuggestions(final SuggestedWords suggestedWords, final CharSequence typedWord) { final CharSequence autoCorrection; if (suggestedWords.size() > 0) { - if (!suggestedWords.shouldBlockAutoCorrectionBySafetyNet() + if (!suggestedWords.mShouldBlockAutoCorrectionBySafetyNet && suggestedWords.hasAutoCorrectionWord()) { autoCorrection = suggestedWords.getWord(1); } else { diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java index 9383c89b1..aad975e46 100644 --- a/java/src/com/android/inputmethod/latin/SuggestedWords.java +++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java @@ -26,18 +26,19 @@ import java.util.HashSet; import java.util.List; public class SuggestedWords { - public static final SuggestedWords EMPTY = new SuggestedWords(null, false, false, false, null); + public static final SuggestedWords EMPTY = new SuggestedWords(null, false, false, false, false, + null); private final List mWords; public final boolean mTypedWordValid; public final boolean mHasAutoCorrectionCandidate; public final boolean mIsPunctuationSuggestions; + public final boolean mShouldBlockAutoCorrectionBySafetyNet; private final List mSuggestedWordInfoList; - // TODO: Make the following member final. - private boolean mShouldBlockAutoCorrectionBySafetyNet; SuggestedWords(List words, boolean typedWordValid, boolean hasAutoCorrectionCandidate, boolean isPunctuationSuggestions, + boolean shouldBlockAutoCorrectionBySafetyNet, List suggestedWordInfoList) { if (words != null) { mWords = words; @@ -47,8 +48,8 @@ public class SuggestedWords { mTypedWordValid = typedWordValid; mHasAutoCorrectionCandidate = hasAutoCorrectionCandidate; mIsPunctuationSuggestions = isPunctuationSuggestions; + mShouldBlockAutoCorrectionBySafetyNet = shouldBlockAutoCorrectionBySafetyNet; mSuggestedWordInfoList = suggestedWordInfoList; - mShouldBlockAutoCorrectionBySafetyNet = false; } public int size() { @@ -67,18 +68,20 @@ public class SuggestedWords { return mHasAutoCorrectionCandidate && size() > 1 && !mTypedWordValid; } - // TODO: Remove this method. - public void setShouldBlockAutoCorrectionBySafetyNet() { - mShouldBlockAutoCorrectionBySafetyNet = true; - } - - public boolean shouldBlockAutoCorrectionBySafetyNet() { - return mShouldBlockAutoCorrectionBySafetyNet; - } - public boolean willAutoCorrect() { return !mTypedWordValid && mHasAutoCorrectionCandidate - && !shouldBlockAutoCorrectionBySafetyNet(); + && !mShouldBlockAutoCorrectionBySafetyNet; + } + + @Override + public String toString() { + // Pretty-print method to help debug + return "SuggestedWords:" + + " mTypedWordValid=" + mTypedWordValid + + " mHasAutoCorrectionCandidate=" + mHasAutoCorrectionCandidate + + " mIsPunctuationSuggestions=" + mIsPunctuationSuggestions + + " mShouldBlockAutoCorrectionBySafetyNet=" + mShouldBlockAutoCorrectionBySafetyNet + + " mWords=" + Arrays.toString(mWords.toArray()); } public static class Builder { @@ -86,6 +89,7 @@ public class SuggestedWords { private boolean mTypedWordValid; private boolean mHasMinimalSuggestion; private boolean mIsPunctuationSuggestions; + private boolean mShouldBlockAutoCorrectionBySafetyNet; private List mSuggestedWordInfoList = new ArrayList(); @@ -150,6 +154,11 @@ public class SuggestedWords { return this; } + public Builder setShouldBlockAutoCorrectionBySafetyNet() { + mShouldBlockAutoCorrectionBySafetyNet = true; + return this; + } + // Should get rid of the first one (what the user typed previously) from suggestions // and replace it with what the user currently typed. public Builder addTypedWordAndPreviousSuggestions(CharSequence typedWord, @@ -175,7 +184,8 @@ public class SuggestedWords { public SuggestedWords build() { return new SuggestedWords(mWords, mTypedWordValid, mHasMinimalSuggestion, - mIsPunctuationSuggestions, mSuggestedWordInfoList); + mIsPunctuationSuggestions, mShouldBlockAutoCorrectionBySafetyNet, + mSuggestedWordInfoList); } public int size() { @@ -186,13 +196,19 @@ public class SuggestedWords { return mWords.get(pos); } + public boolean isTypedWordValid() { + return mTypedWordValid; + } + @Override public String toString() { // Pretty-print method to help debug return "SuggestedWords.Builder:" - + " mTypedWordValid = " + mTypedWordValid - + " mHasMinimalSuggestion = " + mHasMinimalSuggestion - + " mIsPunctuationSuggestions = " + mIsPunctuationSuggestions + + " mTypedWordValid=" + mTypedWordValid + + " mHasMinimalSuggestion=" + mHasMinimalSuggestion + + " mIsPunctuationSuggestions=" + mIsPunctuationSuggestions + + " mShouldBlockAutoCorrectionBySafetyNet=" + + mShouldBlockAutoCorrectionBySafetyNet + " mWords=" + Arrays.toString(mWords.toArray()); } } diff --git a/java/src/com/android/inputmethod/latin/Utils.java b/java/src/com/android/inputmethod/latin/Utils.java index f6bc85431..33d4b877e 100644 --- a/java/src/com/android/inputmethod/latin/Utils.java +++ b/java/src/com/android/inputmethod/latin/Utils.java @@ -190,19 +190,25 @@ public class Utils { // TODO: Resolve the inconsistencies between the native auto correction algorithms and // this safety net - public static boolean shouldBlockAutoCorrectionBySafetyNet(SuggestedWords suggestions, - Suggest suggest) { + public static boolean shouldBlockAutoCorrectionBySafetyNet( + SuggestedWords.Builder suggestedWordsBuilder, Suggest suggest) { // Safety net for auto correction. // Actually if we hit this safety net, it's actually a bug. - if (suggestions.size() <= 1 || suggestions.mTypedWordValid) return false; + if (suggestedWordsBuilder.size() <= 1 || suggestedWordsBuilder.isTypedWordValid()) { + return false; + } // If user selected aggressive auto correction mode, there is no need to use the safety // net. - if (suggest.isAggressiveAutoCorrectionMode()) return false; - final CharSequence typedWord = suggestions.getWord(0); + if (suggest.isAggressiveAutoCorrectionMode()) { + return false; + } + final CharSequence typedWord = suggestedWordsBuilder.getWord(0); // If the length of typed word is less than MINIMUM_SAFETY_NET_CHAR_LENGTH, // we should not use net because relatively edit distance can be big. - if (typedWord.length() < MINIMUM_SAFETY_NET_CHAR_LENGTH) return false; - final CharSequence suggestionWord = suggestions.getWord(1); + if (typedWord.length() < MINIMUM_SAFETY_NET_CHAR_LENGTH) { + return false; + } + final CharSequence suggestionWord = suggestedWordsBuilder.getWord(1); final int typedWordLength = typedWord.length(); final int maxEditDistanceOfNativeDictionary = (typedWordLength < 5 ? 2 : typedWordLength / 2) + 1; diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java index 31c32bdce..d3362940f 100644 --- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java +++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionsView.java @@ -94,7 +94,7 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener, private final TextView mPreviewText; private Listener mListener; - private SuggestedWords mSuggestions = SuggestedWords.EMPTY; + private SuggestedWords mSuggestedWords = SuggestedWords.EMPTY; private final SuggestionsViewParams mParams; private static final float MIN_TEXT_XSCALE = 0.70f; @@ -258,10 +258,10 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener, return a.getFraction(index, 1000, 1000, 1) / 1000.0f; } - private CharSequence getStyledSuggestionWord(SuggestedWords suggestions, int pos) { - final CharSequence word = suggestions.getWord(pos); - final boolean isAutoCorrect = pos == 1 && suggestions.willAutoCorrect(); - final boolean isTypedWordValid = pos == 0 && suggestions.mTypedWordValid; + private CharSequence getStyledSuggestionWord(SuggestedWords suggestedWords, int pos) { + final CharSequence word = suggestedWords.getWord(pos); + final boolean isAutoCorrect = pos == 1 && suggestedWords.willAutoCorrect(); + final boolean isTypedWordValid = pos == 0 && suggestedWords.mTypedWordValid; if (!isAutoCorrect && !isTypedWordValid) return word; @@ -278,10 +278,10 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener, return spannedWord; } - private int getWordPosition(int index, SuggestedWords suggestions) { + private int getWordPosition(int index, SuggestedWords suggestedWords) { // TODO: This works for 3 suggestions. Revisit this algorithm when there are 5 or more // suggestions. - final int centerPos = suggestions.willAutoCorrect() ? 1 : 0; + final int centerPos = suggestedWords.willAutoCorrect() ? 1 : 0; if (index == mCenterSuggestionIndex) { return centerPos; } else if (index == centerPos) { @@ -291,14 +291,14 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener, } } - private int getSuggestionTextColor(int index, SuggestedWords suggestions, int pos) { + private int getSuggestionTextColor(int index, SuggestedWords suggestedWords, int pos) { // TODO: Need to revisit this logic with bigram suggestions final boolean isSuggested = (pos != 0); final int color; - if (index == mCenterSuggestionIndex && suggestions.willAutoCorrect()) { + if (index == mCenterSuggestionIndex && suggestedWords.willAutoCorrect()) { color = mColorAutoCorrect; - } else if (index == mCenterSuggestionIndex && suggestions.mTypedWordValid) { + } else if (index == mCenterSuggestionIndex && suggestedWords.mTypedWordValid) { color = mColorValidTypedWord; } else if (isSuggested) { color = mColorSuggested; @@ -306,14 +306,14 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener, color = mColorTypedWord; } if (LatinImeLogger.sDBG) { - if (index == mCenterSuggestionIndex && suggestions.mHasAutoCorrectionCandidate - && suggestions.shouldBlockAutoCorrectionBySafetyNet()) { + if (index == mCenterSuggestionIndex && suggestedWords.mHasAutoCorrectionCandidate + && suggestedWords.mShouldBlockAutoCorrectionBySafetyNet) { return 0xFFFF0000; } } - final SuggestedWordInfo info = (pos < suggestions.size()) - ? suggestions.getInfo(pos) : null; + final SuggestedWordInfo info = (pos < suggestedWords.size()) + ? suggestedWords.getInfo(pos) : null; if (info != null && info.isObsoleteSuggestedWord()) { return applyAlpha(color, mAlphaObsoleted); } else { @@ -333,19 +333,19 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener, params.gravity = Gravity.CENTER; } - public void layout(SuggestedWords suggestions, ViewGroup stripView, ViewGroup placer, + public void layout(SuggestedWords suggestedWords, ViewGroup stripView, ViewGroup placer, int stripWidth) { - if (suggestions.mIsPunctuationSuggestions) { - layoutPunctuationSuggestions(suggestions, stripView); + if (suggestedWords.mIsPunctuationSuggestions) { + layoutPunctuationSuggestions(suggestedWords, stripView); return; } final int countInStrip = mSuggestionsCountInStrip; - setupTexts(suggestions, countInStrip); - mMoreSuggestionsAvailable = (suggestions.size() > countInStrip); + setupTexts(suggestedWords, countInStrip); + mMoreSuggestionsAvailable = (suggestedWords.size() > countInStrip); int x = 0; for (int index = 0; index < countInStrip; index++) { - final int pos = getWordPosition(index, suggestions); + final int pos = getWordPosition(index, suggestedWords); if (index != 0) { final View divider = mDividers.get(pos); @@ -368,7 +368,7 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener, // Disable this suggestion if the suggestion is null or empty. word.setEnabled(!TextUtils.isEmpty(styled)); - word.setTextColor(getSuggestionTextColor(index, suggestions, pos)); + word.setTextColor(getSuggestionTextColor(index, suggestedWords, pos)); final int width = getSuggestionWidth(index, stripWidth); final CharSequence text = getEllipsizedText(styled, width, word.getPaint()); final float scaleX = word.getTextScaleX(); @@ -380,7 +380,7 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener, x += word.getMeasuredWidth(); if (DBG) { - final CharSequence debugInfo = getDebugInfo(suggestions, pos); + final CharSequence debugInfo = getDebugInfo(suggestedWords, pos); if (debugInfo != null) { final TextView info = mInfos.get(pos); info.setText(debugInfo); @@ -412,11 +412,11 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener, } } - private void setupTexts(SuggestedWords suggestions, int countInStrip) { + private void setupTexts(SuggestedWords suggestedWords, int countInStrip) { mTexts.clear(); - final int count = Math.min(suggestions.size(), countInStrip); + final int count = Math.min(suggestedWords.size(), countInStrip); for (int pos = 0; pos < count; pos++) { - final CharSequence styled = getStyledSuggestionWord(suggestions, pos); + final CharSequence styled = getStyledSuggestionWord(suggestedWords, pos); mTexts.add(styled); } for (int pos = count; pos < countInStrip; pos++) { @@ -425,8 +425,9 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener, } } - private void layoutPunctuationSuggestions(SuggestedWords suggestions, ViewGroup stripView) { - final int countInStrip = Math.min(suggestions.size(), PUNCTUATIONS_IN_STRIP); + private void layoutPunctuationSuggestions(SuggestedWords suggestedWords, + ViewGroup stripView) { + final int countInStrip = Math.min(suggestedWords.size(), PUNCTUATIONS_IN_STRIP); for (int index = 0; index < countInStrip; index++) { if (index != 0) { // Add divider if this isn't the left most suggestion in suggestions strip. @@ -436,7 +437,7 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener, final TextView word = mWords.get(index); word.setEnabled(true); word.setTextColor(mColorAutoCorrect); - final CharSequence text = suggestions.getWord(index); + final CharSequence text = suggestedWords.getWord(index); word.setText(text); word.setTextScaleX(1.0f); word.setCompoundDrawables(null, null, null, null); @@ -635,13 +636,13 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener, mKeyboardView = (KeyboardView)inputView.findViewById(R.id.keyboard_view); } - public void setSuggestions(SuggestedWords suggestions) { - if (suggestions == null || suggestions.size() == 0) + public void setSuggestions(SuggestedWords suggestedWords) { + if (suggestedWords == null || suggestedWords.size() == 0) return; clear(); - mSuggestions = suggestions; - mParams.layout(mSuggestions, mSuggestionsStrip, this, getWidth()); + mSuggestedWords = suggestedWords; + mParams.layout(mSuggestedWords, mSuggestionsStrip, this, getWidth()); } @@ -664,7 +665,7 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener, } public SuggestedWords getSuggestions() { - return mSuggestions; + return mSuggestedWords; } public void clear() { @@ -687,7 +688,7 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener, @Override public boolean onCustomRequest(int requestCode) { final int index = requestCode; - final CharSequence word = mSuggestions.getWord(index); + final CharSequence word = mSuggestedWords.getWord(index); mListener.pickSuggestionManually(index, word); dismissMoreSuggestions(); return true; @@ -732,7 +733,7 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener, final int maxWidth = stripWidth - container.getPaddingLeft() - container.getPaddingRight(); final MoreSuggestions.Builder builder = mMoreSuggestionsBuilder; - builder.layout(mSuggestions, params.mSuggestionsCountInStrip, maxWidth, + builder.layout(mSuggestedWords, params.mSuggestionsCountInStrip, maxWidth, (int)(maxWidth * params.mMinMoreSuggestionsWidth), params.mMaxMoreSuggestionsRow); mMoreSuggestionsView.setKeyboard(builder.build()); @@ -834,10 +835,10 @@ public class SuggestionsView extends RelativeLayout implements OnClickListener, if (!(tag instanceof Integer)) return; final int index = (Integer) tag; - if (index >= mSuggestions.size()) + if (index >= mSuggestedWords.size()) return; - final CharSequence word = mSuggestions.getWord(index); + final CharSequence word = mSuggestedWords.getWord(index); mListener.pickSuggestionManually(index, word); }