diff options
18 files changed, 342 insertions, 122 deletions
diff --git a/java/res/values/themes-lxx.xml b/java/res/values/themes-lxx.xml index 03babd259..8016e76b2 100644 --- a/java/res/values/themes-lxx.xml +++ b/java/res/values/themes-lxx.xml @@ -51,7 +51,7 @@ <item name="functionalKeyBackground">@drawable/btn_keyboard_key_functional_lxx</item> <item name="spacebarBackground">@drawable/btn_keyboard_spacebar_lxx</item> <item name="spacebarIconWidthRatio">0.9</item> - <item name="keyTypeface">bold</item> + <item name="keyTypeface">normal</item> <item name="keyTextColor">@color/key_text_color_holo</item> <item name="keyTextInactivatedColor">@color/key_text_inactive_color_lxx</item> <item name="functionalTextColor">@color/key_hint_letter_color_lxx</item> @@ -116,7 +116,7 @@ <item name="centerSuggestionPercentile">@fraction/config_center_suggestion_percentile</item> <item name="maxMoreSuggestionsRow">@integer/config_max_more_suggestions_row</item> <item name="minMoreSuggestionsWidth">@fraction/config_min_more_suggestions_width</item> - <item name="android:background">@drawable/keyboard_suggest_strip_holo</item> + <item name="android:background">@color/suggestions_strip_background_lxx</item> <item name="suggestionStripOptions">autoCorrectBold|validTypedWordBold</item> <item name="colorValidTypedWord">@color/typed_word_color_lxx</item> <item name="colorTypedWord">@color/typed_word_color_lxx</item> diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardTheme.java b/java/src/com/android/inputmethod/keyboard/KeyboardTheme.java index e0b74fa14..0c0c16229 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardTheme.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardTheme.java @@ -29,8 +29,8 @@ import java.util.Comparator; public final class KeyboardTheme { private static final String TAG = KeyboardTheme.class.getSimpleName(); - static final String KITKAT_KEYBOARD_THEME_KEY = "pref_keyboard_layout_20110916"; - static final String KEYBOARD_THEME_KEY = "pref_keyboard_theme_20140509"; + static final String KLP_KEYBOARD_THEME_KEY = "pref_keyboard_layout_20110916"; + static final String LXX_KEYBOARD_THEME_KEY = "pref_keyboard_theme_20140509"; static final int THEME_ID_ICS = 0; static final int THEME_ID_KLP = 2; @@ -39,9 +39,9 @@ public final class KeyboardTheme { private static final KeyboardTheme[] KEYBOARD_THEMES = { new KeyboardTheme(THEME_ID_ICS, R.style.KeyboardTheme_ICS, - VERSION_CODES.ICE_CREAM_SANDWICH), + VERSION_CODES.BASE), new KeyboardTheme(THEME_ID_KLP, R.style.KeyboardTheme_KLP, - VERSION_CODES.KITKAT), + VERSION_CODES.ICE_CREAM_SANDWICH), new KeyboardTheme(THEME_ID_LXX, R.style.KeyboardTheme_LXX, // TODO: Update this constant once the *next* version becomes available. VERSION_CODES.CUR_DEVELOPMENT), @@ -116,22 +116,23 @@ public final class KeyboardTheme { static KeyboardTheme getDefaultKeyboardTheme(final SharedPreferences prefs, final int sdkVersion) { - final String obsoleteIdString = prefs.getString(KITKAT_KEYBOARD_THEME_KEY, null); - if (obsoleteIdString != null) { - // Remove old preference. - prefs.edit().remove(KITKAT_KEYBOARD_THEME_KEY).apply(); + final String klpThemeIdString = prefs.getString(KLP_KEYBOARD_THEME_KEY, null); + if (klpThemeIdString != null) { if (sdkVersion <= VERSION_CODES.KITKAT) { try { - final int themeId = Integer.parseInt(obsoleteIdString); + final int themeId = Integer.parseInt(klpThemeIdString); final KeyboardTheme theme = searchKeyboardThemeById(themeId); if (theme != null) { return theme; } - Log.w(TAG, "Unknown keyboard theme in preference: " + obsoleteIdString); + Log.w(TAG, "Unknown keyboard theme in KLP preference: " + klpThemeIdString); } catch (final NumberFormatException e) { - Log.w(TAG, "Illegal keyboard theme in preference: " + obsoleteIdString); + Log.w(TAG, "Illegal keyboard theme in KLP preference: " + klpThemeIdString, e); } } + // Remove old preference. + Log.i(TAG, "Remove KLP keyboard theme preference: " + klpThemeIdString); + prefs.edit().remove(KLP_KEYBOARD_THEME_KEY).apply(); } // TODO: This search algorithm isn't optimal if there are many themes. for (final KeyboardTheme theme : KEYBOARD_THEMES) { @@ -144,27 +145,43 @@ public final class KeyboardTheme { public static void saveKeyboardThemeId(final String themeIdString, final SharedPreferences prefs) { - prefs.edit().putString(KEYBOARD_THEME_KEY, themeIdString).apply(); + saveKeyboardThemeId(themeIdString, prefs, getSdkVersion()); + } + + static String getPreferenceKey(final int sdkVersion) { + if (sdkVersion <= VERSION_CODES.KITKAT) { + return KLP_KEYBOARD_THEME_KEY; + } + return LXX_KEYBOARD_THEME_KEY; + } + + static void saveKeyboardThemeId(final String themeIdString, final SharedPreferences prefs, + final int sdkVersion) { + final String prefKey = getPreferenceKey(sdkVersion); + prefs.edit().putString(prefKey, themeIdString).apply(); } public static KeyboardTheme getKeyboardTheme(final SharedPreferences prefs) { - final int sdkVersion = getSdkVersion(); - final String themeIdString = prefs.getString(KEYBOARD_THEME_KEY, null); - if (themeIdString == null) { + return getKeyboardTheme(prefs, getSdkVersion()); + } + + static KeyboardTheme getKeyboardTheme(final SharedPreferences prefs, final int sdkVersion) { + final String lxxThemeIdString = prefs.getString(LXX_KEYBOARD_THEME_KEY, null); + if (lxxThemeIdString == null) { return getDefaultKeyboardTheme(prefs, sdkVersion); } try { - final int themeId = Integer.parseInt(themeIdString); + final int themeId = Integer.parseInt(lxxThemeIdString); final KeyboardTheme theme = searchKeyboardThemeById(themeId); if (theme != null) { return theme; } - Log.w(TAG, "Unknown keyboard theme in preference: " + themeIdString); + Log.w(TAG, "Unknown keyboard theme in LXX preference: " + lxxThemeIdString); } catch (final NumberFormatException e) { - Log.w(TAG, "Illegal keyboard theme in preference: " + themeIdString); + Log.w(TAG, "Illegal keyboard theme in LXX preference: " + lxxThemeIdString, e); } - // Remove preference. - prefs.edit().remove(KEYBOARD_THEME_KEY).apply(); + // Remove preference that contains unknown or illegal theme id. + prefs.edit().remove(LXX_KEYBOARD_THEME_KEY).apply(); return getDefaultKeyboardTheme(prefs, sdkVersion); } } diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java index 1e31c96ec..8a6404b1b 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,20 +263,10 @@ 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 boolean blockOffensiveWords, final int[] additionalFeaturesOptions, final int sessionId, final float[] inOutLanguageWeight) { if (!isValidDictionary()) { return null; diff --git a/java/src/com/android/inputmethod/latin/Dictionary.java b/java/src/com/android/inputmethod/latin/Dictionary.java index cd380db6b..5253cc3dd 100644 --- a/java/src/com/android/inputmethod/latin/Dictionary.java +++ b/java/src/com/android/inputmethod/latin/Dictionary.java @@ -73,6 +73,7 @@ public abstract class Dictionary { * @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. @@ -83,17 +84,7 @@ public abstract class Dictionary { abstract public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, final String prevWord, 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 @@ -167,7 +158,7 @@ public abstract class Dictionary { public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, final String prevWord, 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..239fd067a 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryCollection.java +++ b/java/src/com/android/inputmethod/latin/DictionaryCollection.java @@ -59,20 +59,20 @@ public final class DictionaryCollection extends Dictionary { public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, final String prevWord, 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); + 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); + 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..ddbb196d9 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java +++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java @@ -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, prevWord, 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..4358f84c2 100644 --- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java @@ -366,7 +366,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary { } @Override - public ArrayList<SuggestedWordInfo> getSuggestionsWithSessionId(final WordComposer composer, + public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, final String prevWord, final ProximityInfo proximityInfo, final boolean blockOffensiveWords, final int[] additionalFeaturesOptions, final int sessionId, final float[] inOutLanguageWeight) { @@ -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, prevWord, 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/ReadOnlyBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java index 9f61d6c37..15b12381b 100644 --- a/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/ReadOnlyBinaryDictionary.java @@ -52,20 +52,12 @@ public final class ReadOnlyBinaryDictionary extends Dictionary { 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 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); + 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..71355f418 100644 --- a/java/src/com/android/inputmethod/latin/Suggest.java +++ b/java/src/com/android/inputmethod/latin/Suggest.java @@ -94,8 +94,8 @@ public final class Suggest { 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; diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java index ac6972928..9cf71c7f4 100644 --- a/java/src/com/android/inputmethod/latin/WordComposer.java +++ b/java/src/com/android/inputmethod/latin/WordComposer.java @@ -149,7 +149,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; @@ -331,15 +332,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 diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java index 69d092751..4c23d2210 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java @@ -327,7 +327,7 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session { final ArrayList<SuggestedWordInfo> suggestions = dictInfo.mDictionary.getSuggestions(composer, prevWord, dictInfo.getProximityInfo(), true /* blockOffensiveWords */, - null /* additionalFeaturesOptions */, + null /* additionalFeaturesOptions */, 0 /* sessionId */, null /* inOutLanguageWeight */); if (suggestions != null) { for (final SuggestedWordInfo suggestion : suggestions) { diff --git a/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java b/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java index c99264347..0be256805 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java @@ -54,7 +54,7 @@ public final class DictionaryPool extends LinkedBlockingQueue<DictAndKeyboard> { public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer, final String prevWord, 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..5f6e168b3 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/SynchronouslyLoadedContactsBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/SynchronouslyLoadedContactsBinaryDictionary.java @@ -38,10 +38,10 @@ public final class SynchronouslyLoadedContactsBinaryDictionary extends ContactsB public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer codes, final String prevWordForBigrams, 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); + 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..0499ad234 100644 --- a/java/src/com/android/inputmethod/latin/spellcheck/SynchronouslyLoadedUserBinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/spellcheck/SynchronouslyLoadedUserBinaryDictionary.java @@ -43,10 +43,10 @@ public final class SynchronouslyLoadedUserBinaryDictionary extends UserBinaryDic public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer codes, final String prevWordForBigrams, 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); + 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 577910a31..d277c9fb4 100644 --- a/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java +++ b/java/src/com/android/inputmethod/latin/utils/DistracterFilter.java @@ -125,9 +125,10 @@ public class DistracterFilter { coordinates = mKeyboard.getCoordinates(codePoints); composer.setComposingWord(codePoints, coordinates, prevWord); - 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 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) { diff --git a/tests/src/com/android/inputmethod/keyboard/KeyboardThemeTests.java b/tests/src/com/android/inputmethod/keyboard/KeyboardThemeTests.java index 555b1a47a..fb5231ba6 100644 --- a/tests/src/com/android/inputmethod/keyboard/KeyboardThemeTests.java +++ b/tests/src/com/android/inputmethod/keyboard/KeyboardThemeTests.java @@ -26,7 +26,13 @@ import android.test.suitebuilder.annotation.SmallTest; public class KeyboardThemeTests extends AndroidTestCase { private SharedPreferences mPrefs; + // TODO: Remove this constant once the *next* version becomes available. + private static final int VERSION_CODES_LXX = VERSION_CODES.CUR_DEVELOPMENT; + private static final int THEME_ID_NULL = -1; + private static final int THEME_ID_UNKNOWN = -2; + private static final int THEME_ID_ILLEGAL = -3; + private static final String ILLEGAL_THEME_ID_STRING = "ThisCausesNumberFormatExecption"; private static final int THEME_ID_ICS = KeyboardTheme.THEME_ID_ICS; private static final int THEME_ID_KLP = KeyboardTheme.THEME_ID_KLP; private static final int THEME_ID_LXX = KeyboardTheme.THEME_ID_LXX; @@ -37,57 +43,281 @@ public class KeyboardThemeTests extends AndroidTestCase { mPrefs = PreferenceManager.getDefaultSharedPreferences(getContext()); } + /* + * Helper functions. + */ + + private static boolean isValidKeyboardThemeId(final int themeId) { + switch (themeId) { + case THEME_ID_ICS: + case THEME_ID_KLP: + case THEME_ID_LXX: + return true; + default: + return false; + } + } + + private void setKeyboardThemePreference(final String prefKey, final int themeId) { + final String themeIdString = Integer.toString(themeId); + if (isValidKeyboardThemeId(themeId) || themeId == THEME_ID_UNKNOWN) { + // Set valid theme id to preference. + mPrefs.edit().putString(prefKey, themeIdString).apply(); + return; + } + if (themeId == THEME_ID_NULL) { + // Simulate undefined preference. + mPrefs.edit().remove(prefKey).apply(); + return; + } + // themeId == THEME_ID_ILLEGAL + // Simulate illegal format theme id in preference. + mPrefs.edit().putString(prefKey, ILLEGAL_THEME_ID_STRING).apply(); + } + + private void assertKeyboardTheme(final int sdkVersion, final int expectedThemeId) { + assertEquals(expectedThemeId, KeyboardTheme.getKeyboardTheme(mPrefs, sdkVersion).mThemeId); + } + + /* + * Test keyboard theme preference on the same platform version and the same keyboard version. + */ + + private void assertKeyboardThemePreference(final int sdkVersion, final int oldThemeId, + final int expectedThemeId) { + final String prefKey = KeyboardTheme.getPreferenceKey(sdkVersion); + setKeyboardThemePreference(prefKey, oldThemeId); + assertKeyboardTheme(sdkVersion, expectedThemeId); + } + + private void assertKeyboardThemePreferenceOnKlp(final int sdkVersion) { + final int defaultThemeId = THEME_ID_KLP; + assertKeyboardThemePreference(sdkVersion, THEME_ID_NULL, defaultThemeId); + assertKeyboardThemePreference(sdkVersion, THEME_ID_ICS, THEME_ID_ICS); + assertKeyboardThemePreference(sdkVersion, THEME_ID_KLP, THEME_ID_KLP); + assertKeyboardThemePreference(sdkVersion, THEME_ID_LXX, THEME_ID_LXX); + assertKeyboardThemePreference(sdkVersion, THEME_ID_UNKNOWN, defaultThemeId); + assertKeyboardThemePreference(sdkVersion, THEME_ID_ILLEGAL, defaultThemeId); + } + + public void testKeyboardThemePreferenceOnKlp() { + assertKeyboardThemePreferenceOnKlp(VERSION_CODES.ICE_CREAM_SANDWICH); + assertKeyboardThemePreferenceOnKlp(VERSION_CODES.ICE_CREAM_SANDWICH_MR1); + assertKeyboardThemePreferenceOnKlp(VERSION_CODES.JELLY_BEAN); + assertKeyboardThemePreferenceOnKlp(VERSION_CODES.JELLY_BEAN_MR1); + assertKeyboardThemePreferenceOnKlp(VERSION_CODES.JELLY_BEAN_MR2); + assertKeyboardThemePreferenceOnKlp(VERSION_CODES.KITKAT); + } + + private void assertKeyboardThemePreferenceOnLxx(final int sdkVersion) { + final int defaultThemeId = THEME_ID_LXX; + assertKeyboardThemePreference(sdkVersion, THEME_ID_NULL, defaultThemeId); + assertKeyboardThemePreference(sdkVersion, THEME_ID_ICS, THEME_ID_ICS); + assertKeyboardThemePreference(sdkVersion, THEME_ID_KLP, THEME_ID_KLP); + assertKeyboardThemePreference(sdkVersion, THEME_ID_LXX, THEME_ID_LXX); + assertKeyboardThemePreference(sdkVersion, THEME_ID_UNKNOWN, defaultThemeId); + assertKeyboardThemePreference(sdkVersion, THEME_ID_ILLEGAL, defaultThemeId); + } + + public void testKeyboardThemePreferenceOnLxx() { + assertKeyboardThemePreferenceOnLxx(VERSION_CODES_LXX); + } + + /* + * Test default keyboard theme based on the platform version. + */ + private void assertDefaultKeyboardTheme(final int sdkVersion, final int oldThemeId, final int expectedThemeId) { - if (oldThemeId == THEME_ID_NULL) { - mPrefs.edit().remove(KeyboardTheme.KITKAT_KEYBOARD_THEME_KEY).apply(); - } else { - final String themeIdString = Integer.toString(oldThemeId); - mPrefs.edit().putString(KeyboardTheme.KITKAT_KEYBOARD_THEME_KEY, themeIdString).apply(); - } + final String oldPrefKey = KeyboardTheme.KLP_KEYBOARD_THEME_KEY; + setKeyboardThemePreference(oldPrefKey, oldThemeId); + final KeyboardTheme defaultTheme = KeyboardTheme.getDefaultKeyboardTheme(mPrefs, sdkVersion); + assertNotNull(defaultTheme); assertEquals(expectedThemeId, defaultTheme.mThemeId); - assertFalse(mPrefs.contains(KeyboardTheme.KITKAT_KEYBOARD_THEME_KEY)); + if (sdkVersion <= VERSION_CODES.KITKAT) { + // Old preference must be retained if it is valid. Otherwise it must be pruned. + assertEquals(isValidKeyboardThemeId(oldThemeId), mPrefs.contains(oldPrefKey)); + return; + } + // Old preference must be removed. + assertFalse(mPrefs.contains(oldPrefKey)); } - private void assertDefaultKeyboardThemeICS(final int sdkVersion) { - assertDefaultKeyboardTheme(sdkVersion, THEME_ID_NULL, THEME_ID_ICS); + private void assertDefaultKeyboardThemeOnKlp(final int sdkVersion) { + assertDefaultKeyboardTheme(sdkVersion, THEME_ID_NULL, THEME_ID_KLP); assertDefaultKeyboardTheme(sdkVersion, THEME_ID_ICS, THEME_ID_ICS); assertDefaultKeyboardTheme(sdkVersion, THEME_ID_KLP, THEME_ID_KLP); + assertDefaultKeyboardTheme(sdkVersion, THEME_ID_UNKNOWN, THEME_ID_KLP); + assertDefaultKeyboardTheme(sdkVersion, THEME_ID_ILLEGAL, THEME_ID_KLP); } - private void assertDefaultKeyboardThemeKLP(final int sdkVersion) { - assertDefaultKeyboardTheme(sdkVersion, THEME_ID_NULL, THEME_ID_KLP); - assertDefaultKeyboardTheme(sdkVersion, THEME_ID_ICS, THEME_ID_ICS); - assertDefaultKeyboardTheme(sdkVersion, THEME_ID_KLP, THEME_ID_KLP); + public void testDefaultKeyboardThemeOnKlp() { + assertDefaultKeyboardThemeOnKlp(VERSION_CODES.ICE_CREAM_SANDWICH); + assertDefaultKeyboardThemeOnKlp(VERSION_CODES.ICE_CREAM_SANDWICH_MR1); + assertDefaultKeyboardThemeOnKlp(VERSION_CODES.JELLY_BEAN); + assertDefaultKeyboardThemeOnKlp(VERSION_CODES.JELLY_BEAN_MR1); + assertDefaultKeyboardThemeOnKlp(VERSION_CODES.JELLY_BEAN_MR2); + assertDefaultKeyboardThemeOnKlp(VERSION_CODES.KITKAT); } - private void assertDefaultKeyboardThemeLXX(final int sdkVersion) { + private void assertDefaultKeyboardThemeOnLxx(final int sdkVersion) { // Forced to switch to LXX theme. assertDefaultKeyboardTheme(sdkVersion, THEME_ID_NULL, THEME_ID_LXX); assertDefaultKeyboardTheme(sdkVersion, THEME_ID_ICS, THEME_ID_LXX); assertDefaultKeyboardTheme(sdkVersion, THEME_ID_KLP, THEME_ID_LXX); + assertDefaultKeyboardTheme(sdkVersion, THEME_ID_UNKNOWN, THEME_ID_LXX); + assertDefaultKeyboardTheme(sdkVersion, THEME_ID_ILLEGAL, THEME_ID_LXX); + } + + public void testDefaultKeyboardThemeOnLxx() { + assertDefaultKeyboardThemeOnLxx(VERSION_CODES_LXX); + } + + /* + * Test keyboard theme preference while upgrading the keyboard that doesn't support LXX theme + * to the keyboard that supports LXX theme. + */ + + private void assertUpgradeKeyboardToLxxOn(final int sdkVersion, final int oldThemeId, + final int expectedThemeId) { + setKeyboardThemePreference(KeyboardTheme.KLP_KEYBOARD_THEME_KEY, oldThemeId); + // Clean up new keyboard theme preference to simulate "upgrade to LXX keyboard". + setKeyboardThemePreference(KeyboardTheme.LXX_KEYBOARD_THEME_KEY, THEME_ID_NULL); + + final KeyboardTheme theme = KeyboardTheme.getKeyboardTheme(mPrefs, sdkVersion); + + assertNotNull(theme); + assertEquals(expectedThemeId, theme.mThemeId); + if (sdkVersion <= VERSION_CODES.KITKAT) { + // New preference must not exist. + assertFalse(mPrefs.contains(KeyboardTheme.LXX_KEYBOARD_THEME_KEY)); + // Old preference must be retained if it is valid. Otherwise it must be pruned. + assertEquals(isValidKeyboardThemeId(oldThemeId), + mPrefs.contains(KeyboardTheme.KLP_KEYBOARD_THEME_KEY)); + if (isValidKeyboardThemeId(oldThemeId)) { + // Old preference must have an expected value. + assertEquals(mPrefs.getString(KeyboardTheme.KLP_KEYBOARD_THEME_KEY, null), + Integer.toString(expectedThemeId)); + } + return; + } + // Old preference must be removed. + assertFalse(mPrefs.contains(KeyboardTheme.KLP_KEYBOARD_THEME_KEY)); + // New preference must not exist. + assertFalse(mPrefs.contains(KeyboardTheme.LXX_KEYBOARD_THEME_KEY)); + } + + private void assertUpgradeKeyboardToLxxOnKlp(final int sdkVersion) { + assertUpgradeKeyboardToLxxOn(sdkVersion, THEME_ID_NULL, THEME_ID_KLP); + assertUpgradeKeyboardToLxxOn(sdkVersion, THEME_ID_ICS, THEME_ID_ICS); + assertUpgradeKeyboardToLxxOn(sdkVersion, THEME_ID_KLP, THEME_ID_KLP); + assertUpgradeKeyboardToLxxOn(sdkVersion, THEME_ID_UNKNOWN, THEME_ID_KLP); + assertUpgradeKeyboardToLxxOn(sdkVersion, THEME_ID_ILLEGAL, THEME_ID_KLP); + } + + // Upgrading keyboard on I,J and K. + public void testUpgradeKeyboardToLxxOnKlp() { + assertUpgradeKeyboardToLxxOnKlp(VERSION_CODES.ICE_CREAM_SANDWICH); + assertUpgradeKeyboardToLxxOnKlp(VERSION_CODES.ICE_CREAM_SANDWICH_MR1); + assertUpgradeKeyboardToLxxOnKlp(VERSION_CODES.JELLY_BEAN); + assertUpgradeKeyboardToLxxOnKlp(VERSION_CODES.JELLY_BEAN_MR1); + assertUpgradeKeyboardToLxxOnKlp(VERSION_CODES.JELLY_BEAN_MR2); + assertUpgradeKeyboardToLxxOnKlp(VERSION_CODES.KITKAT); + } + + private void assertUpgradeKeyboardToLxxOnLxx(final int sdkVersion) { + // Forced to switch to LXX theme. + assertUpgradeKeyboardToLxxOn(sdkVersion, THEME_ID_NULL, THEME_ID_LXX); + assertUpgradeKeyboardToLxxOn(sdkVersion, THEME_ID_ICS, THEME_ID_LXX); + assertUpgradeKeyboardToLxxOn(sdkVersion, THEME_ID_KLP, THEME_ID_LXX); + assertUpgradeKeyboardToLxxOn(sdkVersion, THEME_ID_UNKNOWN, THEME_ID_LXX); + assertUpgradeKeyboardToLxxOn(sdkVersion, THEME_ID_ILLEGAL, THEME_ID_LXX); + } + + // Upgrading keyboard on L. + public void testUpgradeKeyboardToLxxOnLxx() { + assertUpgradeKeyboardToLxxOnLxx(VERSION_CODES_LXX); } - public void testDefaultKeyboardThemeICS() { - assertDefaultKeyboardThemeICS(VERSION_CODES.ICE_CREAM_SANDWICH); - assertDefaultKeyboardThemeICS(VERSION_CODES.ICE_CREAM_SANDWICH_MR1); + /* + * Test keyboard theme preference while upgrading platform version. + */ + + private void assertUpgradePlatformFromTo(final int oldSdkVersion, final int newSdkVersion, + final int oldThemeId, final int expectedThemeId) { + if (newSdkVersion < oldSdkVersion) { + // No need to test. + return; + } + // Clean up preferences. + setKeyboardThemePreference(KeyboardTheme.KLP_KEYBOARD_THEME_KEY, THEME_ID_NULL); + setKeyboardThemePreference(KeyboardTheme.LXX_KEYBOARD_THEME_KEY, THEME_ID_NULL); + + final String oldPrefKey = KeyboardTheme.getPreferenceKey(oldSdkVersion); + setKeyboardThemePreference(oldPrefKey, oldThemeId); + + assertKeyboardTheme(newSdkVersion, expectedThemeId); } - public void testDefaultKeyboardThemeJB() { - assertDefaultKeyboardThemeICS(VERSION_CODES.JELLY_BEAN); - assertDefaultKeyboardThemeICS(VERSION_CODES.JELLY_BEAN_MR1); - assertDefaultKeyboardThemeICS(VERSION_CODES.JELLY_BEAN_MR2); + private void assertUpgradePlatformFromKlpToKlp(final int oldSdkVersion, + final int newSdkVersion) { + assertUpgradePlatformFromTo(oldSdkVersion, newSdkVersion, THEME_ID_NULL, THEME_ID_KLP); + assertUpgradePlatformFromTo(oldSdkVersion, newSdkVersion, THEME_ID_ICS, THEME_ID_ICS); + assertUpgradePlatformFromTo(oldSdkVersion, newSdkVersion, THEME_ID_KLP, THEME_ID_KLP); + assertUpgradePlatformFromTo(oldSdkVersion, newSdkVersion, THEME_ID_UNKNOWN, THEME_ID_KLP); + assertUpgradePlatformFromTo(oldSdkVersion, newSdkVersion, THEME_ID_ILLEGAL, THEME_ID_KLP); + } + + private void assertUpgradePlatformToKlpFrom(final int oldSdkVersion) { + assertUpgradePlatformFromKlpToKlp(oldSdkVersion, VERSION_CODES.ICE_CREAM_SANDWICH); + assertUpgradePlatformFromKlpToKlp(oldSdkVersion, VERSION_CODES.ICE_CREAM_SANDWICH_MR1); + assertUpgradePlatformFromKlpToKlp(oldSdkVersion, VERSION_CODES.JELLY_BEAN); + assertUpgradePlatformFromKlpToKlp(oldSdkVersion, VERSION_CODES.JELLY_BEAN_MR1); + assertUpgradePlatformFromKlpToKlp(oldSdkVersion, VERSION_CODES.JELLY_BEAN_MR2); + assertUpgradePlatformFromKlpToKlp(oldSdkVersion, VERSION_CODES.KITKAT); + } + + // Update platform from I,J, and K to I,J, and K + public void testUpgradePlatformToKlpFromKlp() { + assertUpgradePlatformToKlpFrom(VERSION_CODES.ICE_CREAM_SANDWICH); + assertUpgradePlatformToKlpFrom(VERSION_CODES.ICE_CREAM_SANDWICH_MR1); + assertUpgradePlatformToKlpFrom(VERSION_CODES.JELLY_BEAN); + assertUpgradePlatformToKlpFrom(VERSION_CODES.JELLY_BEAN_MR1); + assertUpgradePlatformToKlpFrom(VERSION_CODES.JELLY_BEAN_MR2); + assertUpgradePlatformToKlpFrom(VERSION_CODES.KITKAT); + } + + private void assertUpgradePlatformToLxxFrom(final int oldSdkVersion) { + // Forced to switch to LXX theme. + final int newSdkVersion = VERSION_CODES_LXX; + assertUpgradePlatformFromTo(oldSdkVersion, newSdkVersion, THEME_ID_NULL, THEME_ID_LXX); + assertUpgradePlatformFromTo(oldSdkVersion, newSdkVersion, THEME_ID_ICS, THEME_ID_LXX); + assertUpgradePlatformFromTo(oldSdkVersion, newSdkVersion, THEME_ID_KLP, THEME_ID_LXX); + assertUpgradePlatformFromTo(oldSdkVersion, newSdkVersion, THEME_ID_UNKNOWN, THEME_ID_LXX); + assertUpgradePlatformFromTo(oldSdkVersion, newSdkVersion, THEME_ID_ILLEGAL, THEME_ID_LXX); } - public void testDefaultKeyboardThemeKLP() { - assertDefaultKeyboardThemeKLP(VERSION_CODES.KITKAT); + // Update platform from I,J, and K to L + public void testUpgradePlatformToLxx() { + assertUpgradePlatformToLxxFrom(VERSION_CODES.ICE_CREAM_SANDWICH); + assertUpgradePlatformToLxxFrom(VERSION_CODES.ICE_CREAM_SANDWICH_MR1); + assertUpgradePlatformToLxxFrom(VERSION_CODES.JELLY_BEAN); + assertUpgradePlatformToLxxFrom(VERSION_CODES.JELLY_BEAN_MR1); + assertUpgradePlatformToLxxFrom(VERSION_CODES.JELLY_BEAN_MR2); + assertUpgradePlatformToLxxFrom(VERSION_CODES.KITKAT); } - public void testDefaultKeyboardThemeLXX() { - // TODO: Update this constant once the *next* version becomes available. - assertDefaultKeyboardThemeLXX(VERSION_CODES.CUR_DEVELOPMENT); + // Update platform from L to L. + public void testUpgradePlatformToLxxFromLxx() { + final int oldSdkVersion = VERSION_CODES_LXX; + final int newSdkVersion = VERSION_CODES_LXX; + assertUpgradePlatformFromTo(oldSdkVersion, newSdkVersion, THEME_ID_NULL, THEME_ID_LXX); + assertUpgradePlatformFromTo(oldSdkVersion, newSdkVersion, THEME_ID_ICS, THEME_ID_ICS); + assertUpgradePlatformFromTo(oldSdkVersion, newSdkVersion, THEME_ID_KLP, THEME_ID_KLP); + assertUpgradePlatformFromTo(oldSdkVersion, newSdkVersion, THEME_ID_UNKNOWN, THEME_ID_LXX); + assertUpgradePlatformFromTo(oldSdkVersion, newSdkVersion, THEME_ID_ILLEGAL, THEME_ID_LXX); } } diff --git a/tests/src/com/android/inputmethod/latin/utils/StringAndJsonUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/StringAndJsonUtilsTests.java index 2a4ead383..bdc608a00 100644 --- a/tests/src/com/android/inputmethod/latin/utils/StringAndJsonUtilsTests.java +++ b/tests/src/com/android/inputmethod/latin/utils/StringAndJsonUtilsTests.java @@ -372,4 +372,14 @@ public class StringAndJsonUtilsTests extends AndroidTestCase { assertTrue("copyCodePointsAndReturnCodePointCount throws when array is too small", exceptionHappened); } + + public void testGetTrailingSingleQuotesCount() { + assertEquals(0, StringUtils.getTrailingSingleQuotesCount("")); + assertEquals(1, StringUtils.getTrailingSingleQuotesCount("'")); + assertEquals(5, StringUtils.getTrailingSingleQuotesCount("'''''")); + assertEquals(0, StringUtils.getTrailingSingleQuotesCount("a")); + assertEquals(0, StringUtils.getTrailingSingleQuotesCount("'this")); + assertEquals(1, StringUtils.getTrailingSingleQuotesCount("'word'")); + assertEquals(0, StringUtils.getTrailingSingleQuotesCount("I'm")); + } } |