From 0c8d5ca023d54b7c9ef6c20eb7988288132bacb5 Mon Sep 17 00:00:00 2001 From: Jean Chalard Date: Tue, 26 Apr 2011 16:28:56 +0900 Subject: Fix Eclipse warnings. This change is only there to fix warning issued by Eclipse. It should have absolutely no impact on the program logic. Change-Id: Ie0e242ac6c167297d33de19902340b0f6ecae9e1 --- java/src/com/android/inputmethod/latin/Utils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'java/src/com/android/inputmethod/latin/Utils.java') diff --git a/java/src/com/android/inputmethod/latin/Utils.java b/java/src/com/android/inputmethod/latin/Utils.java index f8b23cb65..b5afb5079 100644 --- a/java/src/com/android/inputmethod/latin/Utils.java +++ b/java/src/com/android/inputmethod/latin/Utils.java @@ -648,6 +648,6 @@ public class Utils { /** Convert pixel to DIP */ public static int dipToPixel(float scale, int dip) { - return (int) ((float) dip * scale + 0.5); + return (int) (dip * scale + 0.5); } } -- cgit v1.2.3-83-g751a From b2e5e5937ca96a448081466a9f43e937787f0c24 Mon Sep 17 00:00:00 2001 From: satok Date: Tue, 26 Apr 2011 14:50:54 +0900 Subject: Handle overflow properly in multiplyRate Bug: 3401513 Change-Id: I8dd2523caa58bb51c378a01e160a58f9106ce9b8 --- java/src/com/android/inputmethod/latin/Utils.java | 6 ++- native/src/unigram_dictionary.cpp | 61 ++++++++++++++++------- 2 files changed, 48 insertions(+), 19 deletions(-) (limited to 'java/src/com/android/inputmethod/latin/Utils.java') diff --git a/java/src/com/android/inputmethod/latin/Utils.java b/java/src/com/android/inputmethod/latin/Utils.java index f8b23cb65..b537b9f8f 100644 --- a/java/src/com/android/inputmethod/latin/Utils.java +++ b/java/src/com/android/inputmethod/latin/Utils.java @@ -48,6 +48,7 @@ public class Utils { private static final String TAG = Utils.class.getSimpleName(); private static final int MINIMUM_SAFETY_NET_CHAR_LENGTH = 4; private static boolean DBG = LatinImeLogger.sDBG; + private static boolean DBG_EDIT_DISTANCE = false; private Utils() { // Intentional empty constructor for utility class. @@ -289,7 +290,7 @@ public class Utils { } } } - if (LatinImeLogger.sDBG) { + if (DBG_EDIT_DISTANCE) { Log.d(TAG, "editDistance:" + s + "," + t); for (int i = 0; i < dp.length; ++i) { StringBuffer sb = new StringBuffer(); @@ -338,6 +339,7 @@ public class Utils { private static final int MAX_INITIAL_SCORE = 255; private static final int TYPED_LETTER_MULTIPLIER = 2; private static final int FULL_WORD_MULTIPLIER = 2; + private static final int S_INT_MAX = 2147483647; public static double calcNormalizedScore(CharSequence before, CharSequence after, int score) { final int beforeLength = before.length(); final int afterLength = after.length(); @@ -352,7 +354,7 @@ public class Utils { } } if (spaceCount == afterLength) return 0; - final double maximumScore = MAX_INITIAL_SCORE + final double maximumScore = score == S_INT_MAX ? S_INT_MAX : MAX_INITIAL_SCORE * Math.pow( TYPED_LETTER_MULTIPLIER, Math.min(beforeLength, afterLength - spaceCount)) * FULL_WORD_MULTIPLIER; diff --git a/native/src/unigram_dictionary.cpp b/native/src/unigram_dictionary.cpp index b9f4b961d..cd2f141cf 100644 --- a/native/src/unigram_dictionary.cpp +++ b/native/src/unigram_dictionary.cpp @@ -300,7 +300,7 @@ bool UnigramDictionary::addWord(unsigned short *word, int length, int frequency) if (DEBUG_DICT) { char s[length + 1]; for (int i = 0; i <= length; i++) s[i] = word[i]; - LOGI("Added word = %s, freq = %d", s, frequency); + LOGI("Added word = %s, freq = %d, %d", s, frequency, S_INT_MAX); } memmove((char*) mFrequencies + (insertAt + 1) * sizeof(mFrequencies[0]), (char*) mFrequencies + insertAt * sizeof(mFrequencies[0]), @@ -409,11 +409,44 @@ void UnigramDictionary::getSuggestionCandidates(const int skipPos, } } -inline static void multiplyRate(const int rate, int *freq) { - if (rate > 1000000) { - *freq = (*freq / 100) * rate; +static const int TWO_31ST_DIV_255 = S_INT_MAX / 255; +static inline int capped255MultForFullMatchAccentsOrCapitalizationDifference(const int num) { + return (num < TWO_31ST_DIV_255 ? 255 * num : S_INT_MAX); +} + +static const int TWO_31ST_DIV_2 = S_INT_MAX / 2; +inline static void multiplyIntCapped(const int multiplier, int *base) { + const int temp = *base; + if (temp != S_INT_MAX) { + // Branch if multiplier == 2 for the optimization + if (multiplier == 2) { + *base = TWO_31ST_DIV_2 >= temp ? temp << 1 : S_INT_MAX; + } else { + const int tempRetval = temp * multiplier; + *base = tempRetval >= temp ? tempRetval : S_INT_MAX; + } + } +} + +inline static int powerIntCapped(const int base, const int n) { + if (false && base == 2) { + return n < 31 ? 1 << n : S_INT_MAX; } else { - *freq = *freq * rate / 100; + int ret = base; + for (int i = 1; i < n; ++i) multiplyIntCapped(base, &ret); + return ret; + } +} + +inline static void multiplyRate(const int rate, int *freq) { + if (*freq != S_INT_MAX) { + if (*freq > 1000000) { + *freq /= 100; + multiplyIntCapped(rate, freq); + } else { + multiplyIntCapped(rate, freq); + *freq /= 100; + } } } @@ -449,9 +482,7 @@ inline static int calcFreqForSplitTwoWords( // (firstFreq * (1 - 1 / (firstWordLength + 1)) + secondFreq * (1 - 1 / (secondWordLength + 1))) // * (1 - 1 / totalLength) / (1 - 1 / (totalLength + 1)) - for (int i = 0; i < totalLength; ++i) { - totalFreq *= typedLetterMultiplier; - } + multiplyIntCapped(powerIntCapped(typedLetterMultiplier, totalLength), &totalFreq); // This is another workaround to offset the demotion which will be done in // calcNormalizedScore in Utils.java. @@ -499,7 +530,7 @@ bool UnigramDictionary::getSplitTwoWordsSuggestion(const int inputLength, int pairFreq = calcFreqForSplitTwoWords( TYPED_LETTER_MULTIPLIER, firstWordLength, secondWordLength, firstFreq, secondFreq); if (DEBUG_DICT) { - LOGI("Missing space: %d, %d, %d, %d, %d", firstFreq, secondFreq, pairFreq, inputLength, + LOGI("Split two words: %d, %d, %d, %d, %d", firstFreq, secondFreq, pairFreq, inputLength, TYPED_LETTER_MULTIPLIER); } addWord(word, newWordLength, pairFreq); @@ -559,10 +590,6 @@ void UnigramDictionary::getWordsRec(const int childrenCount, const int pos, cons } } -static const int TWO_31ST_DIV_255 = S_INT_MAX / 255; -static inline int capped255MultForFullMatchAccentsOrCapitalizationDifference(const int num) { - return (num < TWO_31ST_DIV_255 ? 255 * num : S_INT_MAX); -} inline int UnigramDictionary::calculateFinalFreq(const int inputIndex, const int depth, const int matchWeight, const int skipPos, const int excessivePos, const int transposedPos, const int freq, const bool sameLength) const { @@ -591,7 +618,7 @@ inline int UnigramDictionary::calculateFinalFreq(const int inputIndex, const int } } int lengthFreq = TYPED_LETTER_MULTIPLIER; - for (int i = 0; i < depth; ++i) lengthFreq *= TYPED_LETTER_MULTIPLIER; + multiplyIntCapped(powerIntCapped(TYPED_LETTER_MULTIPLIER, depth), &lengthFreq); if (lengthFreq == matchWeight) { // Full exact match if (depth > 1) { @@ -608,13 +635,13 @@ inline int UnigramDictionary::calculateFinalFreq(const int inputIndex, const int if (DEBUG_DICT) { LOGI("Found one proximity correction."); } - finalFreq *= 2; + multiplyIntCapped(TYPED_LETTER_MULTIPLIER, &finalFreq); multiplyRate(WORDS_WITH_PROXIMITY_CHARACTER_DEMOTION_RATE, &finalFreq); } if (DEBUG_DICT) { LOGI("calc: %d, %d", depth, sameLength); } - if (sameLength) finalFreq *= FULL_WORD_MULTIPLIER; + if (sameLength) multiplyIntCapped(FULL_WORD_MULTIPLIER, &finalFreq); return finalFreq; } @@ -767,7 +794,7 @@ inline bool UnigramDictionary::processCurrentNode(const int pos, const int depth // If inputIndex is greater than mInputLength, that means there is no // proximity chars. So, we don't need to check proximity. if (SAME_OR_ACCENTED_OR_CAPITALIZED_CHAR == matchedProximityCharId) { - matchWeight = matchWeight * TYPED_LETTER_MULTIPLIER; + multiplyIntCapped(TYPED_LETTER_MULTIPLIER, &matchWeight); } bool isSameAsUserTypedLength = mInputLength == inputIndex + 1 || (excessivePos == mInputLength - 1 && inputIndex == mInputLength - 2); -- cgit v1.2.3-83-g751a From 309bff562fbaf47488e6bf6636840f00574187d8 Mon Sep 17 00:00:00 2001 From: Jean Chalard Date: Wed, 27 Apr 2011 15:43:03 +0900 Subject: Add a method to set the locale to Utils. Add a setLocale method to Utils that returns the previous locale. Also unify all calls through the code. Change-Id: Ic850dc5df19fba00ed3601835652859b4321b544 --- .../deprecated/languageswitcher/InputLanguageSelection.java | 9 ++------- .../com/android/inputmethod/keyboard/KeyboardSwitcher.java | 5 +++-- java/src/com/android/inputmethod/latin/LatinIME.java | 6 +++--- java/src/com/android/inputmethod/latin/SubtypeSwitcher.java | 13 ------------- java/src/com/android/inputmethod/latin/Utils.java | 10 ++++++++++ 5 files changed, 18 insertions(+), 25 deletions(-) (limited to 'java/src/com/android/inputmethod/latin/Utils.java') diff --git a/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java b/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java index ce576d0cc..6678082b7 100644 --- a/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java +++ b/java/src/com/android/inputmethod/deprecated/languageswitcher/InputLanguageSelection.java @@ -29,7 +29,6 @@ import org.xmlpull.v1.XmlPullParserException; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; -import android.content.res.Configuration; import android.content.res.Resources; import android.os.Bundle; import android.preference.CheckBoxPreference; @@ -123,10 +122,7 @@ public class InputLanguageSelection extends PreferenceActivity { private Pair hasDictionaryOrLayout(Locale locale) { if (locale == null) return new Pair(false, false); final Resources res = getResources(); - final Configuration conf = res.getConfiguration(); - final Locale saveLocale = conf.locale; - conf.locale = locale; - res.updateConfiguration(conf, res.getDisplayMetrics()); + final Locale saveLocale = Utils.setSystemLocale(res, locale); boolean hasDictionary = false; boolean hasLayout = false; @@ -155,8 +151,7 @@ public class InputLanguageSelection extends PreferenceActivity { } catch (XmlPullParserException e) { } catch (IOException e) { } - conf.locale = saveLocale; - res.updateConfiguration(conf, res.getDisplayMetrics()); + Utils.setSystemLocale(res, saveLocale); return new Pair(hasDictionary, hasLayout); } diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java index e163457d8..8627508e5 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java @@ -164,7 +164,8 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha final SoftReference ref = mKeyboardCache.get(id); LatinKeyboard keyboard = (ref == null) ? null : ref.get(); if (keyboard == null) { - final Locale savedLocale = mSubtypeSwitcher.changeSystemLocale( + final Resources res = mInputMethodService.getResources(); + final Locale savedLocale = Utils.setSystemLocale(res, mSubtypeSwitcher.getInputLocale()); keyboard = new LatinKeyboard(mInputMethodService, id); @@ -178,7 +179,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha Log.d(TAG, "keyboard cache size=" + mKeyboardCache.size() + ": " + ((ref == null) ? "LOAD" : "GCed") + " id=" + id); - mSubtypeSwitcher.changeSystemLocale(savedLocale); + Utils.setSystemLocale(res, savedLocale); } else if (DEBUG) { Log.d(TAG, "keyboard cache size=" + mKeyboardCache.size() + ": HIT id=" + id); } diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 28fd6aad7..175467fcb 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -470,14 +470,14 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar final String localeStr = mSubtypeSwitcher.getInputLocaleStr(); final Locale keyboardLocale = new Locale(localeStr); - final Locale savedLocale = mSubtypeSwitcher.changeSystemLocale(keyboardLocale); + final Resources res = mResources; + final Locale savedLocale = Utils.setSystemLocale(res, keyboardLocale); if (mSuggest != null) { mSuggest.close(); } final SharedPreferences prefs = mPrefs; mQuickFixes = isQuickFixesEnabled(prefs); - final Resources res = mResources; int mainDicResId = Utils.getMainDictionaryResourceId(res); mSuggest = new Suggest(this, mainDicResId, keyboardLocale); loadAndSetAutoCorrectionThreshold(prefs); @@ -499,7 +499,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar mWordSeparators = res.getString(R.string.word_separators); mSentenceSeparators = res.getString(R.string.sentence_separators); - mSubtypeSwitcher.changeSystemLocale(savedLocale); + Utils.setSystemLocale(res, savedLocale); } /* package private */ void resetSuggestMainDict() { diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java index 1925e83ed..d8012087b 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java +++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java @@ -475,19 +475,6 @@ public class SubtypeSwitcher { } } - /** - * Change system locale for this application - * @param newLocale - * @return oldLocale - */ - public Locale changeSystemLocale(Locale newLocale) { - Configuration conf = mResources.getConfiguration(); - Locale oldLocale = conf.locale; - conf.locale = newLocale; - mResources.updateConfiguration(conf, mResources.getDisplayMetrics()); - return oldLocale; - } - public boolean isKeyboardMode() { return KEYBOARD_MODE.equals(getCurrentSubtypeMode()); } diff --git a/java/src/com/android/inputmethod/latin/Utils.java b/java/src/com/android/inputmethod/latin/Utils.java index b5afb5079..9d7b98410 100644 --- a/java/src/com/android/inputmethod/latin/Utils.java +++ b/java/src/com/android/inputmethod/latin/Utils.java @@ -23,6 +23,7 @@ import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.KeyboardId; import android.content.Context; +import android.content.res.Configuration; import android.content.res.Resources; import android.inputmethodservice.InputMethodService; import android.os.AsyncTask; @@ -43,6 +44,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.Locale; public class Utils { private static final String TAG = Utils.class.getSimpleName(); @@ -650,4 +652,12 @@ public class Utils { public static int dipToPixel(float scale, int dip) { return (int) (dip * scale + 0.5); } + + public static Locale setSystemLocale(Resources res, Locale newLocale) { + final Configuration conf = res.getConfiguration(); + final Locale saveLocale = conf.locale; + conf.locale = newLocale; + res.updateConfiguration(conf, res.getDisplayMetrics()); + return saveLocale; + } } -- cgit v1.2.3-83-g751a