aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java35
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java2
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionary.java21
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryFacilitator.java88
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCache.java2
-rw-r--r--java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java60
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java66
-rw-r--r--java/src/com/android/inputmethod/latin/NgramContext.java5
-rw-r--r--java/src/com/android/inputmethod/latin/Suggest.java12
-rw-r--r--java/src/com/android/inputmethod/latin/SuggestedWords.java13
-rw-r--r--java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java14
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/DictionaryHeader.java4
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java31
-rw-r--r--java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java54
-rw-r--r--java/src/com/android/inputmethod/latin/settings/DebugSettings.java4
-rw-r--r--java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java4
-rw-r--r--java/src/com/android/inputmethod/latin/settings/Settings.java2
-rw-r--r--java/src/com/android/inputmethod/latin/settings/SettingsValues.java6
-rw-r--r--java/src/com/android/inputmethod/latin/setup/SetupActivity.java4
-rw-r--r--java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java5
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java18
21 files changed, 281 insertions, 169 deletions
diff --git a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
index c33c01552..d3e24e342 100644
--- a/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
+++ b/java/src/com/android/inputmethod/compat/SuggestionSpanUtils.java
@@ -23,13 +23,18 @@ import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.SuggestionSpan;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.SuggestedWords;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
-import com.android.inputmethod.latin.define.DebugFlags;
import com.android.inputmethod.latin.SuggestionSpanPickedNotificationReceiver;
+import com.android.inputmethod.latin.define.DebugFlags;
+import com.android.inputmethod.latin.utils.LocaleUtils;
import java.lang.reflect.Field;
import java.util.ArrayList;
+import java.util.Locale;
+
+import javax.annotation.Nullable;
public final class SuggestionSpanUtils {
// Note that SuggestionSpan.FLAG_AUTO_CORRECTION has been introduced
@@ -51,12 +56,14 @@ public final class SuggestionSpanUtils {
// This utility class is not publicly instantiable.
}
+ @UsedForTesting
public static CharSequence getTextWithAutoCorrectionIndicatorUnderline(
final Context context, final String text) {
if (TextUtils.isEmpty(text) || OBJ_FLAG_AUTO_CORRECTION == null) {
return text;
}
final Spannable spannable = new SpannableString(text);
+ // TODO: Set locale if it is feasible.
final SuggestionSpan suggestionSpan = new SuggestionSpan(context, null /* locale */,
new String[] {} /* suggestions */, OBJ_FLAG_AUTO_CORRECTION,
SuggestionSpanPickedNotificationReceiver.class);
@@ -65,6 +72,7 @@ public final class SuggestionSpanUtils {
return spannable;
}
+ @UsedForTesting
public static CharSequence getTextWithSuggestionSpan(final Context context,
final String pickedWord, final SuggestedWords suggestedWords) {
if (TextUtils.isEmpty(pickedWord) || suggestedWords.isEmpty()
@@ -86,6 +94,7 @@ public final class SuggestionSpanUtils {
suggestionsList.add(word.toString());
}
}
+ // TODO: Set locale if it is feasible.
final SuggestionSpan suggestionSpan = new SuggestionSpan(context, null /* locale */,
suggestionsList.toArray(new String[suggestionsList.size()]), 0 /* flags */,
SuggestionSpanPickedNotificationReceiver.class);
@@ -93,4 +102,28 @@ public final class SuggestionSpanUtils {
spannable.setSpan(suggestionSpan, 0, pickedWord.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
return spannable;
}
+
+ /**
+ * Returns first {@link Locale} found in the given array of {@link SuggestionSpan}.
+ * @param suggestionSpans the array of {@link SuggestionSpan} to be examined.
+ * @return the first {@link Locale} found in {@code suggestionSpans}. {@code null} when not
+ * found.
+ */
+ @UsedForTesting
+ @Nullable
+ public static Locale findFirstLocaleFromSuggestionSpans(
+ final SuggestionSpan[] suggestionSpans) {
+ for (final SuggestionSpan suggestionSpan : suggestionSpans) {
+ final String localeString = suggestionSpan.getLocale();
+ if (TextUtils.isEmpty(localeString)) {
+ continue;
+ }
+ final Locale locale = LocaleUtils.constructLocaleFromString(localeString);
+ if (locale == null) {
+ continue;
+ }
+ return locale;
+ }
+ return null;
+ }
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
index 031cad0a5..f4e010c4d 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardBuilder.java
@@ -735,7 +735,7 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
private boolean matchLocaleCodes(TypedArray caseAttr, final Locale[] locales) {
// TODO: adujst this for multilingual input
- return matchString(caseAttr, R.styleable.Keyboard_Case_languageCode, locales[0].toString());
+ return matchString(caseAttr, R.styleable.Keyboard_Case_localeCode, locales[0].toString());
}
private boolean matchLanguageCodes(TypedArray caseAttr, Locale[] locales) {
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index 6f3c48c47..10dea749d 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -42,6 +42,8 @@ import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
+import javax.annotation.Nonnull;
+
/**
* Implements a static, compacted, binary dictionary of standard words.
*/
@@ -199,6 +201,7 @@ public final class BinaryDictionary extends Dictionary {
int[] word, int probability, int timestamp);
private static native boolean removeNgramEntryNative(long dict,
int[][] prevWordCodePointArrays, boolean[] isBeginningOfSentenceArray, int[] word);
+ // TODO: Rename to updateEntriesForWordWithNgramContextNative.
private static native boolean updateCounterNative(long dict,
int[][] prevWordCodePointArrays, boolean[] isBeginningOfSentenceArray,
int[] word, boolean isValidWord, int count, int timestamp);
@@ -493,6 +496,24 @@ public final class BinaryDictionary extends Dictionary {
return true;
}
+ // Update entries for the word occurrence with the ngramContext.
+ public boolean updateEntriesForWordWithNgramContext(@Nonnull final NgramContext ngramContext,
+ final String word, final boolean isValidWord, final int count, final int timestamp) {
+ if (TextUtils.isEmpty(word)) {
+ return false;
+ }
+ final int[][] prevWordCodePointArrays = new int[ngramContext.getPrevWordCount()][];
+ final boolean[] isBeginningOfSentenceArray = new boolean[ngramContext.getPrevWordCount()];
+ ngramContext.outputToArray(prevWordCodePointArrays, isBeginningOfSentenceArray);
+ final int[] wordCodePoints = StringUtils.toCodePointArray(word);
+ if (!updateCounterNative(mNativeDict, prevWordCodePointArrays,
+ isBeginningOfSentenceArray, wordCodePoints, isValidWord, count, timestamp)) {
+ return false;
+ }
+ mHasUpdated = true;
+ return true;
+ }
+
@UsedForTesting
public void addMultipleDictionaryEntries(final LanguageModelParam[] languageModelParams) {
if (!isValidDictionary()) return;
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
index 4a218d550..6a63bfda7 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
@@ -62,6 +62,7 @@ public class DictionaryFacilitator {
private static final int CAPITALIZED_FORM_MAX_PROBABILITY_FOR_INSERT = 140;
private DictionaryGroup[] mDictionaryGroups = new DictionaryGroup[] { new DictionaryGroup() };
+ private DictionaryGroup mMostProbableDictionaryGroup = mDictionaryGroups[0];
private boolean mIsUserDictEnabled = false;
private volatile CountDownLatch mLatchForWaitingLoadingMainDictionaries = new CountDownLatch(0);
// To synchronize assigning mDictionaryGroup to ensure closing dictionaries.
@@ -126,9 +127,16 @@ public class DictionaryFacilitator {
* A group of dictionaries that work together for a single language.
*/
private static class DictionaryGroup {
+ // TODO: Run evaluation to determine a reasonable value for these constants. The current
+ // values are ad-hoc and chosen without any particular care or methodology.
+ public static final float WEIGHT_FOR_MOST_PROBABLE_LANGUAGE = 1.0f;
+ public static final float WEIGHT_FOR_GESTURING_IN_NOT_MOST_PROBABLE_LANGUAGE = 0.95f;
+ public static final float WEIGHT_FOR_TYPING_IN_NOT_MOST_PROBABLE_LANGUAGE = 0.6f;
+
public final Locale mLocale;
private Dictionary mMainDict;
- public float mWeightForLocale = 1.0f;
+ public float mWeightForTypingInLocale = WEIGHT_FOR_MOST_PROBABLE_LANGUAGE;
+ public float mWeightForGesturingInLocale = WEIGHT_FOR_MOST_PROBABLE_LANGUAGE;
public final ConcurrentHashMap<String, ExpandableBinaryDictionary> mSubDictMap =
new ConcurrentHashMap<>();
@@ -214,25 +222,52 @@ public class DictionaryFacilitator {
mPersonalizationHelper.updateEnabledSubtypes(enabledSubtypes);
}
+ // TODO: remove this, it's confusing with seamless multiple language switching
public void setIsMonolingualUser(final boolean isMonolingualUser) {
mPersonalizationHelper.setIsMonolingualUser(isMonolingualUser);
}
- // TODO: remove this, replace with version returning multiple locales
- public Locale getLocale() {
- return mDictionaryGroups[0].mLocale;
+ public boolean isActive() {
+ return null != mDictionaryGroups[0].mLocale;
}
/**
- * Returns the primary locale among all currently active locales. BE CAREFUL using this.
+ * Returns the most probable locale among all currently active locales. BE CAREFUL using this.
*
* DO NOT USE THIS just because it's convenient. Use it when it's correct, for example when
* choosing what dictionary to put a word in, or when changing the capitalization of a typed
* string.
- * @return the primary active locale
+ * @return the most probable locale
*/
- public Locale getPrimaryLocale() {
- return mDictionaryGroups[0].mLocale;
+ public Locale getMostProbableLocale() {
+ return getDictionaryGroupForMostProbableLanguage().mLocale;
+ }
+
+ public Locale[] getLocales() {
+ final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
+ final Locale[] locales = new Locale[dictionaryGroups.length];
+ for (int i = 0; i < dictionaryGroups.length; ++i) {
+ locales[i] = dictionaryGroups[i].mLocale;
+ }
+ return locales;
+ }
+
+ private DictionaryGroup getDictionaryGroupForMostProbableLanguage() {
+ return mMostProbableDictionaryGroup;
+ }
+
+ public void switchMostProbableLanguage(final Locale locale) {
+ final DictionaryGroup newMostProbableDictionaryGroup =
+ findDictionaryGroupWithLocale(mDictionaryGroups, locale);
+ mMostProbableDictionaryGroup.mWeightForTypingInLocale =
+ DictionaryGroup.WEIGHT_FOR_TYPING_IN_NOT_MOST_PROBABLE_LANGUAGE;
+ mMostProbableDictionaryGroup.mWeightForGesturingInLocale =
+ DictionaryGroup.WEIGHT_FOR_GESTURING_IN_NOT_MOST_PROBABLE_LANGUAGE;
+ newMostProbableDictionaryGroup.mWeightForTypingInLocale =
+ DictionaryGroup.WEIGHT_FOR_MOST_PROBABLE_LANGUAGE;
+ newMostProbableDictionaryGroup.mWeightForGesturingInLocale =
+ DictionaryGroup.WEIGHT_FOR_MOST_PROBABLE_LANGUAGE;
+ mMostProbableDictionaryGroup = newMostProbableDictionaryGroup;
}
private static ExpandableBinaryDictionary getSubDict(final String dictType,
@@ -256,11 +291,11 @@ public class DictionaryFacilitator {
}
}
- public void resetDictionaries(final Context context, final Locale newLocale,
+ public void resetDictionaries(final Context context, final Locale[] newLocales,
final boolean useContactsDict, final boolean usePersonalizedDicts,
final boolean forceReloadMainDictionary,
final DictionaryInitializationListener listener) {
- resetDictionariesWithDictNamePrefix(context, newLocale, useContactsDict,
+ resetDictionariesWithDictNamePrefix(context, newLocales, useContactsDict,
usePersonalizedDicts, forceReloadMainDictionary, listener, "" /* dictNamePrefix */);
}
@@ -274,20 +309,13 @@ public class DictionaryFacilitator {
return null;
}
- private DictionaryGroup getDictionaryGroupForActiveLanguage() {
- // TODO: implement this
- return mDictionaryGroups[0];
- }
-
public void resetDictionariesWithDictNamePrefix(final Context context,
- final Locale newLocaleToUse,
+ final Locale[] newLocales,
final boolean useContactsDict, final boolean usePersonalizedDicts,
final boolean forceReloadMainDictionary,
final DictionaryInitializationListener listener,
final String dictNamePrefix) {
final HashMap<Locale, ArrayList<String>> existingDictsToCleanup = new HashMap<>();
- // TODO: use several locales
- final Locale[] newLocales = new Locale[] { newLocaleToUse };
// TODO: Make subDictTypesToUse configurable by resource or a static final list.
final HashSet<String> subDictTypesToUse = new HashSet<>();
subDictTypesToUse.add(Dictionary.TYPE_USER);
@@ -359,6 +387,7 @@ public class DictionaryFacilitator {
synchronized (mLock) {
oldDictionaryGroups = mDictionaryGroups;
mDictionaryGroups = newDictionaryGroups;
+ mMostProbableDictionaryGroup = newDictionaryGroups[0];
mIsUserDictEnabled = UserBinaryDictionary.isEnabled(context);
if (hasAtLeastOneUninitializedMainDictionary()) {
asyncReloadUninitializedMainDictionaries(context, newLocales, listener);
@@ -448,13 +477,15 @@ public class DictionaryFacilitator {
dictionaryGroups[i] = new DictionaryGroup(locale, mainDictionary, subDicts);
}
mDictionaryGroups = dictionaryGroups;
+ mMostProbableDictionaryGroup = dictionaryGroups[0];
}
public void closeDictionaries() {
final DictionaryGroup[] dictionaryGroups;
synchronized (mLock) {
dictionaryGroups = mDictionaryGroups;
- mDictionaryGroups = new DictionaryGroup[] { new DictionaryGroup() };
+ mMostProbableDictionaryGroup = new DictionaryGroup();
+ mDictionaryGroups = new DictionaryGroup[] { mMostProbableDictionaryGroup };
}
for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS) {
@@ -469,7 +500,7 @@ public class DictionaryFacilitator {
@UsedForTesting
public ExpandableBinaryDictionary getSubDictForTesting(final String dictName) {
- return mDictionaryGroups[0].getSubDict(dictName);
+ return mMostProbableDictionaryGroup.getSubDict(dictName);
}
// The main dictionaries are loaded asynchronously. Don't cache the return value
@@ -542,17 +573,18 @@ public class DictionaryFacilitator {
}
public void addWordToUserDictionary(final Context context, final String word) {
- final Locale locale = getLocale();
+ final Locale locale = getMostProbableLocale();
if (locale == null) {
return;
}
+ // TODO: add a toast telling what language this is being added to?
UserBinaryDictionary.addWordToUserDictionary(context, locale, word);
}
public void addToUserHistory(final String suggestion, final boolean wasAutoCapitalized,
final NgramContext ngramContext, final int timeStampInSeconds,
final boolean blockPotentiallyOffensive) {
- final DictionaryGroup dictionaryGroup = getDictionaryGroupForActiveLanguage();
+ final DictionaryGroup dictionaryGroup = getDictionaryGroupForMostProbableLanguage();
final String[] words = suggestion.split(Constants.WORD_SEPARATOR);
NgramContext ngramContextForCurrentWord = ngramContext;
for (int i = 0; i < words.length; i++) {
@@ -620,7 +652,7 @@ public class DictionaryFacilitator {
private void removeWord(final String dictName, final String word) {
final ExpandableBinaryDictionary dictionary =
- getDictionaryGroupForActiveLanguage().getSubDict(dictName);
+ getDictionaryGroupForMostProbableLanguage().getSubDict(dictName);
if (dictionary != null) {
dictionary.removeUnigramEntryDynamically(word);
}
@@ -645,10 +677,13 @@ public class DictionaryFacilitator {
for (final String dictType : DICT_TYPES_ORDERED_TO_GET_SUGGESTIONS) {
final Dictionary dictionary = dictionaryGroup.getDict(dictType);
if (null == dictionary) continue;
+ final float weightForLocale = composer.isBatchMode()
+ ? dictionaryGroup.mWeightForGesturingInLocale
+ : dictionaryGroup.mWeightForTypingInLocale;
final ArrayList<SuggestedWordInfo> dictionarySuggestions =
dictionary.getSuggestions(composer, ngramContext, proximityInfo,
settingsValuesForSuggestion, sessionId,
- dictionaryGroup.mWeightForLocale, weightOfLangModelVsSpatialModel);
+ weightForLocale, weightOfLangModelVsSpatialModel);
if (null == dictionarySuggestions) continue;
suggestionResults.addAll(dictionarySuggestions);
if (null != suggestionResults.mRawSuggestions) {
@@ -747,7 +782,8 @@ public class DictionaryFacilitator {
final SpacingAndPunctuations spacingAndPunctuations,
final AddMultipleDictionaryEntriesCallback callback) {
mPersonalizationHelper.addEntriesToPersonalizationDictionariesToUpdate(
- getLocale(), personalizationDataChunk, spacingAndPunctuations, callback);
+ getMostProbableLocale(), personalizationDataChunk, spacingAndPunctuations,
+ callback);
}
@UsedForTesting
@@ -756,7 +792,7 @@ public class DictionaryFacilitator {
// TODO: we're inserting the phrase into the dictionary for the active language. Rethink
// this a bit from a theoretical point of view.
final ExpandableBinaryDictionary contextualDict =
- getDictionaryGroupForActiveLanguage().getSubDict(Dictionary.TYPE_CONTEXTUAL);
+ getDictionaryGroupForMostProbableLanguage().getSubDict(Dictionary.TYPE_CONTEXTUAL);
if (contextualDict == null) {
return;
}
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCache.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCache.java
index ff4a6bde1..1b33d9129 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCache.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorLruCache.java
@@ -101,7 +101,7 @@ public class DictionaryFacilitatorLruCache {
private void resetDictionariesForLocaleLocked(final DictionaryFacilitator dictionaryFacilitator,
final Locale locale) {
- dictionaryFacilitator.resetDictionariesWithDictNamePrefix(mContext, locale,
+ dictionaryFacilitator.resetDictionariesWithDictNamePrefix(mContext, new Locale[] { locale },
mUseContactsDictionary, false /* usePersonalizedDicts */,
false /* forceReloadMainDictionary */, null /* listener */,
mDictionaryNamePrefix);
diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
index 1bdadc30b..d24f80a45 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
@@ -46,6 +46,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
+import javax.annotation.Nonnull;
+
/**
* Abstract base class for an expandable dictionary that can be created and updated dynamically
* during runtime. When updated it automatically generates a new binary dictionary to handle future
@@ -292,13 +294,9 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
}
}
- /**
- * Adds unigram information of a word to the dictionary. May overwrite an existing entry.
- */
- public void addUnigramEntryWithCheckingDistracter(final String word, final int frequency,
- final String shortcutTarget, final int shortcutFreq, final boolean isNotAWord,
- final boolean isBlacklisted, final int timestamp,
- final DistracterFilter distracterFilter) {
+ private void updateDictionaryWithWriteLockIfWordIsNotADistracter(
+ @Nonnull final Runnable updateTask,
+ @Nonnull final String word, @Nonnull final DistracterFilter distracterFilter) {
reloadDictionaryIfRequired();
asyncPreCheckAndExecuteTaskWithWriteLock(
new Callable<Boolean>() {
@@ -315,12 +313,27 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
return;
}
runGCIfRequiredLocked(true /* mindsBlockByGC */);
- addUnigramLocked(word, frequency, shortcutTarget, shortcutFreq,
- isNotAWord, isBlacklisted, timestamp);
+ updateTask.run();
}
});
}
+ /**
+ * Adds unigram information of a word to the dictionary. May overwrite an existing entry.
+ */
+ public void addUnigramEntryWithCheckingDistracter(final String word, final int frequency,
+ final String shortcutTarget, final int shortcutFreq, final boolean isNotAWord,
+ final boolean isBlacklisted, final int timestamp,
+ @Nonnull final DistracterFilter distracterFilter) {
+ updateDictionaryWithWriteLockIfWordIsNotADistracter(new Runnable() {
+ @Override
+ public void run() {
+ addUnigramLocked(word, frequency, shortcutTarget, shortcutFreq,
+ isNotAWord, isBlacklisted, timestamp);
+ }
+ }, word, distracterFilter);
+ }
+
protected void addUnigramLocked(final String word, final int frequency,
final String shortcutTarget, final int shortcutFreq, final boolean isNotAWord,
final boolean isBlacklisted, final int timestamp) {
@@ -354,7 +367,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
/**
* Adds n-gram information of a word to the dictionary. May overwrite an existing entry.
*/
- public void addNgramEntry(final NgramContext ngramContext, final String word,
+ public void addNgramEntry(@Nonnull final NgramContext ngramContext, final String word,
final int frequency, final int timestamp) {
reloadDictionaryIfRequired();
asyncExecuteTaskWithWriteLock(new Runnable() {
@@ -369,7 +382,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
});
}
- protected void addNgramEntryLocked(final NgramContext ngramContext, final String word,
+ protected void addNgramEntryLocked(@Nonnull final NgramContext ngramContext, final String word,
final int frequency, final int timestamp) {
if (!mBinaryDictionary.addNgramEntry(ngramContext, word, frequency, timestamp)) {
if (DEBUG) {
@@ -383,7 +396,8 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
* Dynamically remove the n-gram entry in the dictionary.
*/
@UsedForTesting
- public void removeNgramDynamically(final NgramContext ngramContext, final String word) {
+ public void removeNgramDynamically(@Nonnull final NgramContext ngramContext,
+ final String word) {
reloadDictionaryIfRequired();
asyncExecuteTaskWithWriteLock(new Runnable() {
@Override
@@ -402,6 +416,26 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
});
}
+ /**
+ * Update dictionary for the word with the ngramContext if the word is not a distracter.
+ */
+ public void updateEntriesForWordWithCheckingDistracter(@Nonnull final NgramContext ngramContext,
+ final String word, final boolean isValidWord, final int count, final int timestamp,
+ @Nonnull final DistracterFilter distracterFilter) {
+ updateDictionaryWithWriteLockIfWordIsNotADistracter(new Runnable() {
+ @Override
+ public void run() {
+ if (!mBinaryDictionary.updateEntriesForWordWithNgramContext(ngramContext, word,
+ isValidWord, count, timestamp)) {
+ if (DEBUG) {
+ Log.e(TAG, "Cannot update counter. word: " + word
+ + " context: "+ ngramContext.toString());
+ }
+ }
+ }
+ }, word, distracterFilter);
+ }
+
public interface AddMultipleDictionaryEntriesCallback {
public void onFinished();
}
@@ -410,7 +444,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
* Dynamically add multiple entries to the dictionary.
*/
public void addMultipleDictionaryEntriesDynamically(
- final ArrayList<LanguageModelParam> languageModelParams,
+ @Nonnull final ArrayList<LanguageModelParam> languageModelParams,
final AddMultipleDictionaryEntriesCallback callback) {
reloadDictionaryIfRequired();
asyncExecuteTaskWithWriteLock(new Runnable() {
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 6b7007e5e..77477d2d3 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -32,6 +32,7 @@ import android.content.res.Resources;
import android.inputmethodservice.InputMethodService;
import android.media.AudioManager;
import android.net.ConnectivityManager;
+import android.os.Build;
import android.os.Debug;
import android.os.IBinder;
import android.os.Message;
@@ -120,12 +121,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private static boolean DEBUG = false;
private static final int EXTENDED_TOUCHABLE_REGION_HEIGHT = 100;
-
- private static final int PENDING_IMS_CALLBACK_DURATION = 800;
-
- private static final int DELAY_WAIT_FOR_DICTIONARY_LOAD = 2000; // 2s
-
private static final int PERIOD_FOR_AUDIO_AND_HAPTIC_FEEDBACK_IN_KEY_REPEAT = 2;
+ private static final int PENDING_IMS_CALLBACK_DURATION_MILLIS = 800;
+ private static final long DELAY_WAIT_FOR_DICTIONARY_LOAD_MILLIS = TimeUnit.SECONDS.toMillis(2);
+ private static final long DELAY_DEALLOCATE_MEMORY_MILLIS = TimeUnit.SECONDS.toMillis(10);
/**
* The name of the scheme used by the Package Manager to warn of a new package installation,
@@ -193,8 +192,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private static final int MSG_UPDATE_TAIL_BATCH_INPUT_COMPLETED = 6;
private static final int MSG_RESET_CACHES = 7;
private static final int MSG_WAIT_FOR_DICTIONARY_LOAD = 8;
+ private static final int MSG_DEALLOCATE_MEMORY = 9;
// Update this when adding new messages
- private static final int MSG_LAST = MSG_WAIT_FOR_DICTIONARY_LOAD;
+ private static final int MSG_LAST = MSG_DEALLOCATE_MEMORY;
private static final int ARG1_NOT_GESTURE_INPUT = 0;
private static final int ARG1_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT = 1;
@@ -281,6 +281,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
case MSG_WAIT_FOR_DICTIONARY_LOAD:
Log.i(TAG, "Timeout waiting for dictionary load");
break;
+ case MSG_DEALLOCATE_MEMORY:
+ latinIme.deallocateMemory();
+ break;
}
}
@@ -318,7 +321,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
public void postWaitForDictionaryLoad() {
sendMessageDelayed(obtainMessage(MSG_WAIT_FOR_DICTIONARY_LOAD),
- DELAY_WAIT_FOR_DICTIONARY_LOAD);
+ DELAY_WAIT_FOR_DICTIONARY_LOAD_MILLIS);
}
public void cancelWaitForDictionaryLoad() {
@@ -347,6 +350,19 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mDelayInMillisecondsToUpdateShiftState);
}
+ public void postDeallocateMemory() {
+ sendMessageDelayed(obtainMessage(MSG_DEALLOCATE_MEMORY),
+ DELAY_DEALLOCATE_MEMORY_MILLIS);
+ }
+
+ public void cancelDeallocateMemory() {
+ removeMessages(MSG_DEALLOCATE_MEMORY);
+ }
+
+ public boolean hasPendingDeallocateMemory() {
+ return hasMessages(MSG_DEALLOCATE_MEMORY);
+ }
+
@UsedForTesting
public void removeAllMessages() {
for (int i = 0; i <= MSG_LAST; ++i) {
@@ -444,7 +460,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mPendingSuccessiveImsCallback = false;
resetPendingImsCallback();
sendMessageDelayed(obtainMessage(MSG_PENDING_IMS_CALLBACK),
- PENDING_IMS_CALLBACK_DURATION);
+ PENDING_IMS_CALLBACK_DURATION_MILLIS);
}
final LatinIME latinIme = getOwnerInstance();
if (latinIme != null) {
@@ -452,6 +468,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
latinIme.onStartInputViewInternal(editorInfo, restarting);
mAppliedEditorInfo = editorInfo;
}
+ cancelDeallocateMemory();
}
}
@@ -465,6 +482,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
latinIme.onFinishInputViewInternal(finishingInput);
mAppliedEditorInfo = null;
}
+ if (!hasPendingDeallocateMemory()) {
+ postDeallocateMemory();
+ }
}
}
@@ -657,9 +677,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// TODO: make sure the current settings always have the right locales, and read from them
private void resetDictionaryFacilitatorForLocale(final Locale[] locales) {
final SettingsValues settingsValues = mSettings.getCurrent();
- // TODO: pass the array instead
- final Locale locale = locales[0];
- mDictionaryFacilitator.resetDictionaries(this /* context */, locale,
+ mDictionaryFacilitator.resetDictionaries(this /* context */, locales,
settingsValues.mUseContactsDict, settingsValues.mUsePersonalizedDicts,
false /* forceReloadMainDictionary */, this);
if (settingsValues.mAutoCorrectionEnabledPerUserSettings) {
@@ -674,7 +692,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
/* package private */ void resetSuggestMainDict() {
final SettingsValues settingsValues = mSettings.getCurrent();
mDictionaryFacilitator.resetDictionaries(this /* context */,
- mDictionaryFacilitator.getLocale(), settingsValues.mUseContactsDict,
+ mDictionaryFacilitator.getLocales(), settingsValues.mUseContactsDict,
settingsValues.mUsePersonalizedDicts, true /* forceReloadMainDictionary */, this);
}
@@ -758,12 +776,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (prevExtractEditText == nextExtractEditText) {
return;
}
- if (ProductionFlags.ENABLE_CURSOR_ANCHOR_INFO_CALLBACK && prevExtractEditText != null) {
+ if (prevExtractEditText != null) {
prevExtractEditText.getViewTreeObserver().removeOnPreDrawListener(
mExtractTextViewPreDrawListener);
}
mExtractEditText = nextExtractEditText;
- if (ProductionFlags.ENABLE_CURSOR_ANCHOR_INFO_CALLBACK && mExtractEditText != null) {
+ if (mExtractEditText != null) {
mExtractEditText.getViewTreeObserver().addOnPreDrawListener(
mExtractTextViewPreDrawListener);
}
@@ -779,8 +797,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
};
private void onExtractTextViewPreDraw() {
- if (!ProductionFlags.ENABLE_CURSOR_ANCHOR_INFO_CALLBACK || !isFullscreenMode()
- || mExtractEditText == null) {
+ // CursorAnchorInfo is available on L and later.
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.L) {
+ return;
+ }
+ if (!isFullscreenMode() || mExtractEditText == null) {
return;
}
final CursorAnchorInfo info = CursorAnchorInfoUtils.getCursorAnchorInfo(mExtractEditText);
@@ -1030,13 +1051,16 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
private void cleanupInternalStateForFinishInput() {
- mKeyboardSwitcher.deallocateMemory();
// Remove pending messages related to update suggestions
mHandler.cancelUpdateSuggestionStrip();
// Should do the following in onFinishInputInternal but until JB MR2 it's not called :(
mInputLogic.finishInput();
}
+ protected void deallocateMemory() {
+ mKeyboardSwitcher.deallocateMemory();
+ }
+
@Override
public void onUpdateSelection(final int oldSelStart, final int oldSelEnd,
final int newSelStart, final int newSelEnd,
@@ -1063,7 +1087,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// We cannot mark this method as @Override until new SDK becomes publicly available.
// @Override
public void onUpdateCursorAnchorInfo(final CursorAnchorInfo info) {
- if (!ProductionFlags.ENABLE_CURSOR_ANCHOR_INFO_CALLBACK || isFullscreenMode()) {
+ if (isFullscreenMode()) {
return;
}
mInputLogic.onUpdateCursorAnchorInfo(CursorAnchorInfoCompatWrapper.fromObject(info));
@@ -1609,7 +1633,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
final String wordToShow;
if (CapsModeUtils.isAutoCapsMode(mInputLogic.mLastComposedWord.mCapitalizedMode)) {
- wordToShow = word.toLowerCase(mDictionaryFacilitator.getPrimaryLocale());
+ wordToShow = word.toLowerCase(mDictionaryFacilitator.getMostProbableLocale());
} else {
wordToShow = word;
}
@@ -1875,7 +1899,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@UsedForTesting
/* package for test */ void replaceDictionariesForTest(final Locale locale) {
final SettingsValues settingsValues = mSettings.getCurrent();
- mDictionaryFacilitator.resetDictionaries(this, locale,
+ mDictionaryFacilitator.resetDictionaries(this, new Locale[] { locale },
settingsValues.mUseContactsDict, settingsValues.mUsePersonalizedDicts,
false /* forceReloadMainDictionary */, this /* listener */);
}
@@ -1894,7 +1918,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
public void dumpDictionaryForDebug(final String dictName) {
- if (mDictionaryFacilitator.getLocale() == null) {
+ if (!mDictionaryFacilitator.isActive()) {
resetDictionaryFacilitatorIfNecessary();
}
mDictionaryFacilitator.dumpDictionaryForDebug(dictName);
diff --git a/java/src/com/android/inputmethod/latin/NgramContext.java b/java/src/com/android/inputmethod/latin/NgramContext.java
index 6d438584f..a02531cc4 100644
--- a/java/src/com/android/inputmethod/latin/NgramContext.java
+++ b/java/src/com/android/inputmethod/latin/NgramContext.java
@@ -158,11 +158,6 @@ public class NgramContext {
}
}
- public NgramContext getTrimmedNgramContext(final int maxPrevWordCount) {
- final int newSize = Math.min(maxPrevWordCount, mPrevWordsCount);
- return new NgramContext(this /* prevWordsInfo */, newSize);
- }
-
public int getPrevWordCount() {
return mPrevWordsCount;
}
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index d2d9b9b1e..e181237a6 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -55,10 +55,6 @@ public final class Suggest {
mDictionaryFacilitator = dictionaryFacilitator;
}
- public Locale getLocale() {
- return mDictionaryFacilitator.getLocale();
- }
-
public void setAutoCorrectionThreshold(final float threshold) {
mAutoCorrectionThreshold = threshold;
}
@@ -136,7 +132,10 @@ public final class Suggest {
SESSION_ID_TYPING);
final ArrayList<SuggestedWordInfo> suggestionsContainer =
getTransformedSuggestedWordInfoList(wordComposer, suggestionResults,
- trailingSingleQuotesCount, mDictionaryFacilitator.getLocale());
+ trailingSingleQuotesCount,
+ // For transforming suggestions that don't come for any dictionary, we
+ // use the currently most probable locale as it's our best bet.
+ mDictionaryFacilitator.getMostProbableLocale());
final boolean didRemoveTypedWord =
SuggestedWordInfo.removeDups(wordComposer.getTypedWord(), suggestionsContainer);
@@ -216,7 +215,8 @@ public final class Suggest {
final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults(
wordComposer, ngramContext, proximityInfo, settingsValuesForSuggestion,
SESSION_ID_GESTURE);
- final Locale defaultLocale = mDictionaryFacilitator.getLocale();
+ // For transforming words that don't come from a dictionary, because it's our best bet
+ final Locale defaultLocale = mDictionaryFacilitator.getMostProbableLocale();
final ArrayList<SuggestedWordInfo> suggestionsContainer =
new ArrayList<>(suggestionResults);
final int suggestionsCount = suggestionsContainer.size();
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index e6fd43a07..466576465 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -113,6 +113,19 @@ public class SuggestedWords {
}
/**
+ * Get suggested word to show as suggestions to UI.
+ *
+ * @param shouldShowLxxSuggestionUi true if showing suggestion UI introduced in LXX and later.
+ * @return the count of suggested word to show as suggestions to UI.
+ */
+ public int getWordCountToShow(final boolean shouldShowLxxSuggestionUi) {
+ if (isPrediction() || !shouldShowLxxSuggestionUi) {
+ return size();
+ }
+ return size() - /* typed word */ 1;
+ }
+
+ /**
* Get suggested word at <code>index</code>.
* @param index The index of the suggested word.
* @return The suggested word.
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index 1b1d5e7e5..07bfd0dee 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -53,7 +53,6 @@ import com.android.inputmethod.latin.SuggestedWords;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.WordComposer;
import com.android.inputmethod.latin.define.DebugFlags;
-import com.android.inputmethod.latin.define.ProductionFlags;
import com.android.inputmethod.latin.settings.SettingsValues;
import com.android.inputmethod.latin.settings.SettingsValuesForSuggestion;
import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
@@ -169,14 +168,11 @@ public final class InputLogic {
mInputLogicHandler.reset();
}
- if (ProductionFlags.ENABLE_CURSOR_ANCHOR_INFO_CALLBACK) {
- // AcceptTypedWord feature relies on CursorAnchorInfo.
- if (settingsValues.mShouldShowUiToAcceptTypedWord) {
- mConnection.requestCursorUpdates(true /* enableMonitor */,
- true /* requestImmediateCallback */);
- }
- mTextDecorator.reset();
+ if (settingsValues.mShouldShowLxxSuggestionUi) {
+ mConnection.requestCursorUpdates(true /* enableMonitor */,
+ true /* requestImmediateCallback */);
}
+ mTextDecorator.reset();
}
/**
@@ -2355,7 +2351,7 @@ public final class InputLogic {
// We cannot help in this case because we are heavily relying on this new API.
return false;
}
- if (!settingsValues.mShouldShowUiToAcceptTypedWord) {
+ if (!settingsValues.mShouldShowLxxSuggestionUi) {
return false;
}
if (TextUtils.isEmpty(lastComposedWord.mTypedWord)) {
diff --git a/java/src/com/android/inputmethod/latin/makedict/DictionaryHeader.java b/java/src/com/android/inputmethod/latin/makedict/DictionaryHeader.java
index 3f9ffd285..fa7c2c417 100644
--- a/java/src/com/android/inputmethod/latin/makedict/DictionaryHeader.java
+++ b/java/src/com/android/inputmethod/latin/makedict/DictionaryHeader.java
@@ -38,12 +38,8 @@ public final class DictionaryHeader {
public static final String DICTIONARY_DATE_KEY = "date";
public static final String HAS_HISTORICAL_INFO_KEY = "HAS_HISTORICAL_INFO";
public static final String USES_FORGETTING_CURVE_KEY = "USES_FORGETTING_CURVE";
- public static final String FORGETTING_CURVE_OCCURRENCES_TO_LEVEL_UP_KEY =
- "FORGETTING_CURVE_OCCURRENCES_TO_LEVEL_UP";
public static final String FORGETTING_CURVE_PROBABILITY_VALUES_TABLE_ID_KEY =
"FORGETTING_CURVE_PROBABILITY_VALUES_TABLE_ID";
- public static final String FORGETTING_CURVE_DURATION_TO_LEVEL_DOWN_IN_SECONDS_KEY =
- "FORGETTING_CURVE_DURATION_TO_LEVEL_DOWN_IN_SECONDS";
public static final String MAX_UNIGRAM_COUNT_KEY = "MAX_UNIGRAM_COUNT";
public static final String MAX_BIGRAM_COUNT_KEY = "MAX_BIGRAM_COUNT";
public static final String ATTRIBUTE_VALUE_TRUE = "1";
diff --git a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java
index d61684698..59761547d 100644
--- a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java
@@ -65,34 +65,7 @@ public class UserHistoryDictionary extends DecayingExpandableBinaryDictionaryBas
if (word.length() > Constants.DICTIONARY_MAX_WORD_LENGTH) {
return;
}
- final int frequency = isValid ?
- FREQUENCY_FOR_WORDS_IN_DICTS : FREQUENCY_FOR_WORDS_NOT_IN_DICTS;
- userHistoryDictionary.addUnigramEntryWithCheckingDistracter(word, frequency,
- null /* shortcutTarget */, 0 /* shortcutFreq */, false /* isNotAWord */,
- false /* isBlacklisted */, timestamp, distracterFilter);
-
- final boolean isBeginningOfSentenceContext = ngramContext.isBeginningOfSentenceContext();
- final NgramContext ngramContextToBeSaved =
- ngramContext.getTrimmedNgramContext(SUPPORTED_NGRAM - 1);
- for (int i = 0; i < ngramContextToBeSaved.getPrevWordCount(); i++) {
- final CharSequence prevWord = ngramContextToBeSaved.getNthPrevWord(1 /* n */);
- if (prevWord == null || (prevWord.length() > Constants.DICTIONARY_MAX_WORD_LENGTH)) {
- return;
- }
- // Do not insert a word as a bigram of itself
- if (i == 0 && TextUtils.equals(word, prevWord)) {
- return;
- }
- if (isBeginningOfSentenceContext) {
- // Beginning-of-Sentence n-gram entry is added as an n-gram entry of an OOV word.
- userHistoryDictionary.addNgramEntry(
- ngramContextToBeSaved.getTrimmedNgramContext(i + 1), word,
- FREQUENCY_FOR_WORDS_NOT_IN_DICTS, timestamp);
- } else {
- userHistoryDictionary.addNgramEntry(
- ngramContextToBeSaved.getTrimmedNgramContext(i + 1), word, frequency,
- timestamp);
- }
- }
+ userHistoryDictionary.updateEntriesForWordWithCheckingDistracter(ngramContext, word,
+ isValid, 1 /* count */, timestamp, distracterFilter);
}
}
diff --git a/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java
index 2174f5224..c633fc167 100644
--- a/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/CustomInputStyleSettingsFragment.java
@@ -33,7 +33,6 @@ import android.preference.PreferenceGroup;
import android.support.v4.view.ViewCompat;
import android.text.TextUtils;
import android.util.Log;
-import android.util.Pair;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@@ -80,25 +79,26 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment {
"is_subtype_enabler_notification_dialog_open";
private static final String KEY_SUBTYPE_FOR_SUBTYPE_ENABLER = "subtype_for_subtype_enabler";
- static final class SubtypeLocaleItem extends Pair<String, String>
- implements Comparable<SubtypeLocaleItem> {
- public SubtypeLocaleItem(final String localeString, final String displayName) {
- super(localeString, displayName);
- }
+ static final class SubtypeLocaleItem implements Comparable<SubtypeLocaleItem> {
+ public final String mLocaleString;
+ private final String mDisplayName;
- public SubtypeLocaleItem(final String localeString) {
- this(localeString,
- SubtypeLocaleUtils.getSubtypeLocaleDisplayNameInSystemLocale(localeString));
+ public SubtypeLocaleItem(final InputMethodSubtype subtype) {
+ mLocaleString = subtype.getLocale();
+ mDisplayName = SubtypeLocaleUtils.getSubtypeLocaleDisplayNameInSystemLocale(
+ mLocaleString);
}
+ // {@link ArrayAdapter<T>} that hosts the instance of this class needs {@link #toString()}
+ // to get display name.
@Override
public String toString() {
- return second;
+ return mDisplayName;
}
@Override
public int compareTo(final SubtypeLocaleItem o) {
- return first.compareTo(o.first);
+ return mLocaleString.compareTo(o.mLocaleString);
}
}
@@ -121,32 +121,28 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment {
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(subtype)));
}
if (InputMethodSubtypeCompatUtils.isAsciiCapable(subtype)) {
- items.add(createItem(context, subtype.getLocale()));
+ items.add(new SubtypeLocaleItem(subtype));
}
}
// TODO: Should filter out already existing combinations of locale and layout.
addAll(items);
}
-
- public static SubtypeLocaleItem createItem(final Context context,
- final String localeString) {
- if (localeString.equals(SubtypeLocaleUtils.NO_LANGUAGE)) {
- final String displayName = context.getString(R.string.subtype_no_language);
- return new SubtypeLocaleItem(localeString, displayName);
- }
- return new SubtypeLocaleItem(localeString);
- }
}
- static final class KeyboardLayoutSetItem extends Pair<String, String> {
+ static final class KeyboardLayoutSetItem {
+ public final String mLayoutName;
+ private final String mDisplayName;
+
public KeyboardLayoutSetItem(final InputMethodSubtype subtype) {
- super(SubtypeLocaleUtils.getKeyboardLayoutSetName(subtype),
- SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(subtype));
+ mLayoutName = SubtypeLocaleUtils.getKeyboardLayoutSetName(subtype);
+ mDisplayName = SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(subtype);
}
+ // {@link ArrayAdapter<T>} that hosts the instance of this class needs {@link #toString()}
+ // to get display name.
@Override
public String toString() {
- return second;
+ return mDisplayName;
}
}
@@ -255,7 +251,6 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment {
@Override
protected void onPrepareDialogBuilder(final AlertDialog.Builder builder) {
- final Context context = builder.getContext();
builder.setCancelable(true).setOnCancelListener(this);
if (isIncomplete()) {
builder.setPositiveButton(R.string.add, this)
@@ -264,8 +259,7 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment {
builder.setPositiveButton(R.string.save, this)
.setNeutralButton(android.R.string.cancel, this)
.setNegativeButton(R.string.remove, this);
- final SubtypeLocaleItem localeItem = SubtypeLocaleAdapter.createItem(
- context, mSubtype.getLocale());
+ final SubtypeLocaleItem localeItem = new SubtypeLocaleItem(mSubtype);
final KeyboardLayoutSetItem layoutItem = new KeyboardLayoutSetItem(mSubtype);
setSpinnerPosition(mSubtypeLocaleSpinner, localeItem);
setSpinnerPosition(mKeyboardLayoutSetSpinner, layoutItem);
@@ -303,7 +297,7 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment {
(KeyboardLayoutSetItem) mKeyboardLayoutSetSpinner.getSelectedItem();
final InputMethodSubtype subtype =
AdditionalSubtypeUtils.createAsciiEmojiCapableAdditionalSubtype(
- locale.first, layout.first);
+ locale.mLocaleString, layout.mLayoutName);
setSubtype(subtype);
notifyChanged();
if (isEditing) {
@@ -469,8 +463,6 @@ public final class CustomInputStyleSettingsFragment extends PreferenceFragment {
KEY_IS_SUBTYPE_ENABLER_NOTIFICATION_DIALOG_OPEN)) {
mSubtypePreferenceKeyForSubtypeEnabler = savedInstanceState.getString(
KEY_SUBTYPE_FOR_SUBTYPE_ENABLER);
- final SubtypePreference subtypePref = (SubtypePreference)findPreference(
- mSubtypePreferenceKeyForSubtypeEnabler);
mSubtypeEnablerNotificationDialog = createDialog();
mSubtypeEnablerNotificationDialog.show();
}
diff --git a/java/src/com/android/inputmethod/latin/settings/DebugSettings.java b/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
index 48f4c758c..091ca43c6 100644
--- a/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
+++ b/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
@@ -21,8 +21,8 @@ public final class DebugSettings {
public static final String PREF_FORCE_NON_DISTINCT_MULTITOUCH = "force_non_distinct_multitouch";
public static final String PREF_FORCE_PHYSICAL_KEYBOARD_SPECIAL_KEY =
"force_physical_keyboard_special_key";
- public static final String PREF_SHOW_UI_TO_ACCEPT_TYPED_WORD =
- "pref_show_ui_to_accept_typed_word";
+ public static final String PREF_SHOULD_SHOW_LXX_SUGGESTION_UI =
+ "pref_should_show_lxx_suggestion_ui";
public static final String PREF_HAS_CUSTOM_KEY_PREVIEW_ANIMATION_PARAMS =
"pref_has_custom_key_preview_animation_params";
public static final String PREF_KEY_PREVIEW_SHOW_UP_START_X_SCALE =
diff --git a/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java
index 5640e2039..e9f8d45aa 100644
--- a/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java
@@ -56,8 +56,8 @@ public final class DebugSettingsFragment extends SubScreenFragment
super.onCreate(icicle);
addPreferencesFromResource(R.xml.prefs_screen_debug);
- if (!Settings.HAS_UI_TO_ACCEPT_TYPED_WORD) {
- removePreference(DebugSettings.PREF_SHOW_UI_TO_ACCEPT_TYPED_WORD);
+ if (!Settings.SHOULD_SHOW_LXX_SUGGESTION_UI) {
+ removePreference(DebugSettings.PREF_SHOULD_SHOW_LXX_SUGGESTION_UI);
}
mReadExternalDictionaryPref = findPreference(PREF_READ_EXTERNAL_DICTIONARY);
diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java
index 83adb1c55..84596b4ad 100644
--- a/java/src/com/android/inputmethod/latin/settings/Settings.java
+++ b/java/src/com/android/inputmethod/latin/settings/Settings.java
@@ -77,7 +77,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
BuildCompatUtils.EFFECTIVE_SDK_INT <= Build.VERSION_CODES.KITKAT;
public static final boolean ENABLE_SHOW_LANGUAGE_SWITCH_KEY_SETTINGS =
BuildCompatUtils.EFFECTIVE_SDK_INT <= Build.VERSION_CODES.KITKAT;
- public static final boolean HAS_UI_TO_ACCEPT_TYPED_WORD =
+ public static final boolean SHOULD_SHOW_LXX_SUGGESTION_UI =
BuildCompatUtils.EFFECTIVE_SDK_INT >= BuildCompatUtils.VERSION_CODES_LXX;
public static final String PREF_SHOW_LANGUAGE_SWITCH_KEY =
"pref_show_language_switch_key";
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
index 99f761ca6..ce8a0ab9c 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
@@ -80,7 +80,7 @@ public class SettingsValues {
public final boolean mPhraseGestureEnabled;
public final int mKeyLongpressTimeout;
public final boolean mEnableMetricsLogging;
- public final boolean mShouldShowUiToAcceptTypedWord;
+ public final boolean mShouldShowLxxSuggestionUi;
// Use split layout for keyboard.
public final boolean mIsSplitKeyboardEnabled;
public final int mScreenMetrics;
@@ -163,8 +163,8 @@ public class SettingsValues {
mIsSplitKeyboardEnabled = prefs.getBoolean(Settings.PREF_ENABLE_SPLIT_KEYBOARD, false);
mScreenMetrics = res.getInteger(R.integer.config_screen_metrics);
- mShouldShowUiToAcceptTypedWord = Settings.HAS_UI_TO_ACCEPT_TYPED_WORD
- && prefs.getBoolean(DebugSettings.PREF_SHOW_UI_TO_ACCEPT_TYPED_WORD, true);
+ mShouldShowLxxSuggestionUi = Settings.SHOULD_SHOW_LXX_SUGGESTION_UI
+ && prefs.getBoolean(DebugSettings.PREF_SHOULD_SHOW_LXX_SUGGESTION_UI, true);
// Compute other readable settings
mKeyLongpressTimeout = Settings.readKeyLongpressTimeout(prefs, res);
mKeypressVibrationDuration = Settings.readKeypressVibrationDuration(prefs, res);
diff --git a/java/src/com/android/inputmethod/latin/setup/SetupActivity.java b/java/src/com/android/inputmethod/latin/setup/SetupActivity.java
index b770ea512..7607429f8 100644
--- a/java/src/com/android/inputmethod/latin/setup/SetupActivity.java
+++ b/java/src/com/android/inputmethod/latin/setup/SetupActivity.java
@@ -17,12 +17,8 @@
package com.android.inputmethod.latin.setup;
import android.app.Activity;
-import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
-import android.provider.Settings;
-import android.view.inputmethod.InputMethodInfo;
-import android.view.inputmethod.InputMethodManager;
public final class SetupActivity extends Activity {
@Override
diff --git a/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java b/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java
index e455e53d3..54562f39d 100644
--- a/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java
+++ b/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java
@@ -46,6 +46,8 @@ import java.util.ArrayList;
public final class SetupWizardActivity extends Activity implements View.OnClickListener {
static final String TAG = SetupWizardActivity.class.getSimpleName();
+ // For debugging purpose.
+ private static final boolean FORCE_TO_SHOW_WELCOME_SCREEN = false;
private static final boolean ENABLE_WELCOME_VIDEO = true;
private InputMethodManager mImm;
@@ -304,6 +306,9 @@ public final class SetupWizardActivity extends Activity implements View.OnClickL
private int determineSetupStepNumber() {
mHandler.cancelPollingImeSettings();
+ if (FORCE_TO_SHOW_WELCOME_SCREEN) {
+ return STEP_1;
+ }
if (!UncachedInputMethodManagerUtils.isThisImeEnabled(this, mImm)) {
return STEP_1;
}
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
index a651774c6..d55939971 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java
@@ -240,9 +240,9 @@ final class SuggestionStripLayoutHelper {
final SettingsValues settingsValues = Settings.getInstance().getCurrent();
final boolean shouldOmitTypedWord = shouldOmitTypedWord(suggestedWords.mInputStyle,
settingsValues.mGestureFloatingPreviewTextEnabled,
- settingsValues.mShouldShowUiToAcceptTypedWord);
+ settingsValues.mShouldShowLxxSuggestionUi);
return getPositionInSuggestionStrip(indexInSuggestedWords, suggestedWords.mWillAutoCorrect,
- settingsValues.mShouldShowUiToAcceptTypedWord && shouldOmitTypedWord,
+ settingsValues.mShouldShowLxxSuggestionUi && shouldOmitTypedWord,
mCenterPositionInStrip, mTypedWordPositionWhenAutocorrect);
}
@@ -367,21 +367,19 @@ final class SuggestionStripLayoutHelper {
(PunctuationSuggestions)suggestedWords, stripView);
}
- final boolean shouldShowUiToAcceptTypedWord = Settings.getInstance().getCurrent()
- .mShouldShowUiToAcceptTypedWord;
- final int suggestionsCount = suggestedWords.size()
- - (shouldShowUiToAcceptTypedWord ? /* typed word */ 1 : 0);
+ final int wordCountToShow = suggestedWords.getWordCountToShow(
+ Settings.getInstance().getCurrent().mShouldShowLxxSuggestionUi);
final int startIndexOfMoreSuggestions = setupWordViewsAndReturnStartIndexOfMoreSuggestions(
suggestedWords, mSuggestionsCountInStrip);
final TextView centerWordView = mWordViews.get(mCenterPositionInStrip);
final int stripWidth = stripView.getWidth();
final int centerWidth = getSuggestionWidth(mCenterPositionInStrip, stripWidth);
- if (suggestionsCount == 1 || getTextScaleX(centerWordView.getText(), centerWidth,
+ if (wordCountToShow == 1 || getTextScaleX(centerWordView.getText(), centerWidth,
centerWordView.getPaint()) < MIN_TEXT_XSCALE) {
// Layout only the most relevant suggested word at the center of the suggestion strip
// by consolidating all slots in the strip.
final int countInStrip = 1;
- mMoreSuggestionsAvailable = (suggestionsCount > countInStrip);
+ mMoreSuggestionsAvailable = (wordCountToShow > countInStrip);
layoutWord(mCenterPositionInStrip, stripWidth - mPadding);
stripView.addView(centerWordView);
setLayoutWeight(centerWordView, 1.0f, ViewGroup.LayoutParams.MATCH_PARENT);
@@ -393,7 +391,7 @@ final class SuggestionStripLayoutHelper {
}
final int countInStrip = mSuggestionsCountInStrip;
- mMoreSuggestionsAvailable = (suggestionsCount > countInStrip);
+ mMoreSuggestionsAvailable = (wordCountToShow > countInStrip);
int x = 0;
for (int positionInStrip = 0; positionInStrip < countInStrip; positionInStrip++) {
if (positionInStrip != 0) {
@@ -557,7 +555,7 @@ final class SuggestionStripLayoutHelper {
public void layoutAddToDictionaryHint(final String word, final ViewGroup addToDictionaryStrip) {
final boolean shouldShowUiToAcceptTypedWord = Settings.getInstance().getCurrent()
- .mShouldShowUiToAcceptTypedWord;
+ .mShouldShowLxxSuggestionUi;
final int stripWidth = addToDictionaryStrip.getWidth();
final int width = shouldShowUiToAcceptTypedWord ? stripWidth
: stripWidth - mDividerWidth - mPadding * 2;