aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/dictionarypack/ActionBatch.java2
-rw-r--r--java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java2
-rw-r--r--java/src/com/android/inputmethod/keyboard/emoji/EmojiPalettesView.java3
-rw-r--r--java/src/com/android/inputmethod/latin/BinaryDictionary.java16
-rw-r--r--java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java3
-rw-r--r--java/src/com/android/inputmethod/latin/ContactsContentObserver.java4
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryFacilitator.java18
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java11
-rw-r--r--java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java5
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java26
-rw-r--r--java/src/com/android/inputmethod/latin/NgramContext.java16
-rw-r--r--java/src/com/android/inputmethod/latin/PunctuationSuggestions.java3
-rw-r--r--java/src/com/android/inputmethod/latin/RichInputMethodSubtype.java3
-rw-r--r--java/src/com/android/inputmethod/latin/Suggest.java92
-rw-r--r--java/src/com/android/inputmethod/latin/SuggestedWords.java32
-rw-r--r--java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java189
-rw-r--r--java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java68
-rw-r--r--java/src/com/android/inputmethod/latin/makedict/FormatSpec.java6
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java3
-rw-r--r--java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java46
-rw-r--r--java/src/com/android/inputmethod/latin/settings/CorrectionSettingsFragment.java17
-rw-r--r--java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java13
-rw-r--r--java/src/com/android/inputmethod/latin/settings/Settings.java30
-rw-r--r--java/src/com/android/inputmethod/latin/settings/SettingsActivity.java17
-rw-r--r--java/src/com/android/inputmethod/latin/settings/SettingsValues.java25
-rw-r--r--java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java2
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/UserDictionaryLookup.java6
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java3
-rw-r--r--java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java57
-rw-r--r--java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java8
-rw-r--r--java/src/com/android/inputmethod/latin/utils/ManagedProfileUtils.java16
-rw-r--r--java/src/com/android/inputmethod/latin/utils/NgramContextUtils.java14
32 files changed, 331 insertions, 425 deletions
diff --git a/java/src/com/android/inputmethod/dictionarypack/ActionBatch.java b/java/src/com/android/inputmethod/dictionarypack/ActionBatch.java
index 3aa026e77..12fdd69b9 100644
--- a/java/src/com/android/inputmethod/dictionarypack/ActionBatch.java
+++ b/java/src/com/android/inputmethod/dictionarypack/ActionBatch.java
@@ -172,6 +172,8 @@ public final class ActionBatch {
final long downloadId = UpdateHandler.registerDownloadRequest(manager, request, db,
mWordList.mId, mWordList.mVersion);
+ Log.i(TAG, String.format("Starting the dictionary download with version:"
+ + " %d and Url: %s" + mWordList.mVersion, uri));
DebugLogUtils.l("Starting download of", uri, "with id", downloadId);
PrivateLog.log("Starting download of " + uri + ", id : " + downloadId);
}
diff --git a/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java b/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java
index 73621f474..b00a811bb 100644
--- a/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java
+++ b/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java
@@ -48,7 +48,7 @@ public class MetadataDbHelper extends SQLiteOpenHelper {
private static final int METADATA_DATABASE_VERSION_WITH_CLIENTID = 6;
// The current database version.
// This MUST be increased every time the dictionary pack metadata URL changes.
- private static final int CURRENT_METADATA_DATABASE_VERSION = 12;
+ private static final int CURRENT_METADATA_DATABASE_VERSION = 14;
private final static long NOT_A_DOWNLOAD_ID = -1;
diff --git a/java/src/com/android/inputmethod/keyboard/emoji/EmojiPalettesView.java b/java/src/com/android/inputmethod/keyboard/emoji/EmojiPalettesView.java
index f4c4f1aab..a3b869d73 100644
--- a/java/src/com/android/inputmethod/keyboard/emoji/EmojiPalettesView.java
+++ b/java/src/com/android/inputmethod/keyboard/emoji/EmojiPalettesView.java
@@ -151,6 +151,9 @@ public final class EmojiPalettesView extends LinearLayout implements OnTabChange
tspec.setContent(R.id.emoji_keyboard_dummy);
final ImageView iconView = (ImageView)LayoutInflater.from(getContext()).inflate(
R.layout.emoji_keyboard_tab_icon, null);
+ // TODO: Replace background color with its own setting rather than using the
+ // category page indicator background as a workaround.
+ iconView.setBackgroundColor(mCategoryPageIndicatorBackground);
iconView.setImageResource(mEmojiCategory.getCategoryTabIcon(categoryId));
iconView.setContentDescription(mEmojiCategory.getAccessibilityDescription(categoryId));
tspec.setIndicator(iconView);
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
index c1015511b..9a3ac674e 100644
--- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java
@@ -27,7 +27,6 @@ import com.android.inputmethod.latin.common.Constants;
import com.android.inputmethod.latin.common.FileUtils;
import com.android.inputmethod.latin.common.InputPointers;
import com.android.inputmethod.latin.common.StringUtils;
-import com.android.inputmethod.latin.define.DecoderSpecificConstants;
import com.android.inputmethod.latin.makedict.DictionaryHeader;
import com.android.inputmethod.latin.makedict.FormatSpec;
import com.android.inputmethod.latin.makedict.FormatSpec.DictionaryOptions;
@@ -58,6 +57,9 @@ public final class BinaryDictionary extends Dictionary {
// Must be equal to CONFIDENCE_TO_AUTO_COMMIT in native/jni/src/defines.h
private static final int CONFIDENCE_TO_AUTO_COMMIT = 1000000;
+ public static final int DICTIONARY_MAX_WORD_LENGTH = 48;
+ public static final int MAX_PREV_WORD_COUNT_FOR_N_GRAM = 3;
+
@UsedForTesting
public static final String UNIGRAM_COUNT_QUERY = "UNIGRAM_COUNT";
@UsedForTesting
@@ -318,16 +320,18 @@ public final class BinaryDictionary extends Dictionary {
final int count = session.mOutputSuggestionCount[0];
final ArrayList<SuggestedWordInfo> suggestions = new ArrayList<>();
for (int j = 0; j < count; ++j) {
- final int start = j * DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH;
+ final int start = j * DICTIONARY_MAX_WORD_LENGTH;
int len = 0;
- while (len < DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH
+ while (len < DICTIONARY_MAX_WORD_LENGTH
&& session.mOutputCodePoints[start + len] != 0) {
++len;
}
if (len > 0) {
suggestions.add(new SuggestedWordInfo(
new String(session.mOutputCodePoints, start, len),
- (int)(session.mOutputScores[j] * weightForLocale), session.mOutputTypes[j],
+ "" /* prevWordsContext */,
+ (int)(session.mOutputScores[j] * weightForLocale),
+ session.mOutputTypes[j],
this /* sourceDict */,
session.mSpaceIndices[j] /* indexOfTouchPointOfSecondWord */,
session.mOutputAutoCommitFirstWordConfidence[0]));
@@ -389,7 +393,7 @@ public final class BinaryDictionary extends Dictionary {
return null;
}
final int[] codePoints = StringUtils.toCodePointArray(word);
- final int[] outCodePoints = new int[DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH];
+ final int[] outCodePoints = new int[DICTIONARY_MAX_WORD_LENGTH];
final boolean[] outFlags = new boolean[FORMAT_WORD_PROPERTY_OUTPUT_FLAG_COUNT];
final int[] outProbabilityInfo =
new int[FORMAT_WORD_PROPERTY_OUTPUT_PROBABILITY_INFO_COUNT];
@@ -428,7 +432,7 @@ public final class BinaryDictionary extends Dictionary {
* If token is 0, this method newly starts iterating the dictionary.
*/
public GetNextWordPropertyResult getNextWordProperty(final int token) {
- final int[] codePoints = new int[DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH];
+ final int[] codePoints = new int[DICTIONARY_MAX_WORD_LENGTH];
final boolean[] isBeginningOfSentence = new boolean[1];
final int nextToken = getNextWordNative(mNativeDict, token, codePoints,
isBeginningOfSentence);
diff --git a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
index ba0f9b807..15a14e5af 100644
--- a/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ContactsBinaryDictionary.java
@@ -125,7 +125,8 @@ public class ContactsBinaryDictionary extends ExpandableBinaryDictionary
*/
private void addNameLocked(final String name) {
int len = StringUtils.codePointCount(name);
- NgramContext ngramContext = NgramContext.EMPTY_PREV_WORDS_INFO;
+ NgramContext ngramContext = NgramContext.getEmptyPrevWordsContext(
+ BinaryDictionary.MAX_PREV_WORD_COUNT_FOR_N_GRAM);
// TODO: Better tokenization for non-Latin writing systems
for (int i = 0; i < len; i++) {
if (Character.isLetter(name.codePointAt(i))) {
diff --git a/java/src/com/android/inputmethod/latin/ContactsContentObserver.java b/java/src/com/android/inputmethod/latin/ContactsContentObserver.java
index 4a8d1133b..5eb9b16d1 100644
--- a/java/src/com/android/inputmethod/latin/ContactsContentObserver.java
+++ b/java/src/com/android/inputmethod/latin/ContactsContentObserver.java
@@ -56,8 +56,8 @@ public class ContactsContentObserver implements Runnable {
mContentObserver = new ContentObserver(null /* handler */) {
@Override
public void onChange(boolean self) {
- // TODO(zivkovic): Schedule a separate task to reset the decoder.
- ExecutorUtils.getBackgroundExecutor().execute(ContactsContentObserver.this);
+ ExecutorUtils.getBackgroundExecutor(ExecutorUtils.KEYBOARD)
+ .execute(ContactsContentObserver.this);
}
};
final ContentResolver contentResolver = mContext.getContentResolver();
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
index 5f981a009..6b49f9aa6 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
@@ -89,6 +89,24 @@ public interface DictionaryFacilitator {
void onUpdateMainDictionaryAvailability(boolean isMainDictionaryAvailable);
}
+ /**
+ * Called every time {@link LatinIME} starts on a new text field.
+ * Dot not affect {@link AndroidSpellCheckerService}.
+ *
+ * WARNING: The service methods that call start/finish are very spammy.
+ */
+ void onStartInput();
+
+ /**
+ * Called every time the {@link LatinIME} finishes with the current text field.
+ * May be followed by {@link #onStartInput} again in another text field,
+ * or it may be done for a while.
+ * Dot not affect {@link AndroidSpellCheckerService}.
+ *
+ * WARNING: The service methods that call start/finish are very spammy.
+ */
+ void onFinishInput();
+
boolean isActive();
Locale getLocale();
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java
index 2f3c58251..e5d770aee 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java
@@ -202,6 +202,15 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
public DictionaryFacilitatorImpl() {
}
+ @Override
+ public void onStartInput() {
+ }
+
+ @Override
+ public void onFinishInput() {
+ }
+
+ @Override
public boolean isActive() {
return mDictionaryGroup.mLocale != null;
}
@@ -338,7 +347,7 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
final Locale locale, final DictionaryInitializationListener listener) {
final CountDownLatch latchForWaitingLoadingMainDictionary = new CountDownLatch(1);
mLatchForWaitingLoadingMainDictionaries = latchForWaitingLoadingMainDictionary;
- ExecutorUtils.getBackgroundExecutor().execute(new Runnable() {
+ ExecutorUtils.getBackgroundExecutor(ExecutorUtils.KEYBOARD).execute(new Runnable() {
@Override
public void run() {
doReloadUninitializedMainDictionaries(
diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
index 138a2ea5c..80daedd50 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
@@ -121,8 +121,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
private static boolean needsToMigrateDictionary(final int formatVersion) {
// When we bump up the dictionary format version, the old version should be added to here
// for supporting migration. Note that native code has to support reading such formats.
- return formatVersion == FormatSpec.VERSION4_ONLY_FOR_TESTING
- || formatVersion == FormatSpec.VERSION402;
+ return formatVersion == FormatSpec.VERSION402;
}
public boolean isValidDictionaryLocked() {
@@ -168,7 +167,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
}
private static void asyncExecuteTaskWithLock(final Lock lock, final Runnable task) {
- ExecutorUtils.getBackgroundExecutor().execute(new Runnable() {
+ ExecutorUtils.getBackgroundExecutor(ExecutorUtils.KEYBOARD).execute(new Runnable() {
@Override
public void run() {
lock.lock();
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index a0e55c65f..330be377b 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -94,7 +94,6 @@ import com.android.inputmethod.latin.utils.ViewLayoutUtils;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
@@ -793,6 +792,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@SuppressWarnings("deprecation")
void onStartInputViewInternal(final EditorInfo editorInfo, final boolean restarting) {
super.onStartInputView(editorInfo, restarting);
+
+ mDictionaryFacilitator.onStartInput();
// Switch to the null consumer to handle cases leading to early exit below, for which we
// also wouldn't be consuming gesture data.
mGestureConsumer = GestureConsumer.NULL_GESTURE_CONSUMER;
@@ -971,6 +972,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
void onFinishInputInternal() {
super.onFinishInput();
+ mDictionaryFacilitator.onFinishInput();
final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
if (mainKeyboardView != null) {
mainKeyboardView.closing();
@@ -1255,7 +1257,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// Implement {@link ImportantNoticeDialog.ImportantNoticeDialogListener}
@Override
public void onClickSettingsOfImportantNoticeDialog(final int nextVersion) {
- launchSettings();
+ launchSettings(SettingsActivity.EXTRA_ENTRY_VALUE_NOTICE_DIALOG);
}
// Implement {@link ImportantNoticeDialog.ImportantNoticeDialogListener}
@@ -1384,7 +1386,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@Override
public void onUpdateBatchInput(final InputPointers batchPointers) {
- mInputLogic.onUpdateBatchInput(mSettings.getCurrent(), batchPointers, mKeyboardSwitcher);
+ mInputLogic.onUpdateBatchInput(batchPointers);
}
@Override
@@ -1408,7 +1410,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
*/
public void onTailBatchInputResultShown(final SuggestedWords suggestedWords) {
mGestureConsumer.onImeSuggestionsProcessed(suggestedWords,
- mInputLogic.getComposingStart(), mInputLogic.getComposingLength());
+ mInputLogic.getComposingStart(), mInputLogic.getComposingLength(),
+ mDictionaryFacilitator);
}
// This method must run on the UI Thread.
@@ -1451,7 +1454,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
final boolean shouldShowImportantNotice =
- ImportantNoticeUtils.shouldShowImportantNotice(this);
+ ImportantNoticeUtils.shouldShowImportantNotice(this, currentSettingsValues);
final boolean shouldShowSuggestionCandidates =
currentSettingsValues.mInputAttributes.mShouldShowSuggestions
&& currentSettingsValues.isSuggestionsEnabledPerUserSettings();
@@ -1531,10 +1534,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// punctuation suggestions (if it's disabled).
@Override
public void setNeutralSuggestionStrip() {
- setSuggestedWords(SuggestedWords.getEmptyInstance());
+ final SettingsValues currentSettings = mSettings.getCurrent();
+ final SuggestedWords neutralSuggestions = currentSettings.mBigramPredictionEnabled
+ ? SuggestedWords.getEmptyInstance()
+ : currentSettings.mSpacingAndPunctuations.mSuggestPuncList;
+ setSuggestedWords(neutralSuggestions);
}
- // TODO: Make this private
// Outside LatinIME, only used by the {@link InputTestsBase} test suite.
@UsedForTesting
void loadKeyboard() {
@@ -1692,7 +1698,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
};
- void launchSettings() {
+ void launchSettings(final String extraEntryValue) {
mInputLogic.commitTyped(mSettings.getCurrent(), LastComposedWord.NOT_A_SEPARATOR);
requestHideSelf(0);
final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
@@ -1705,6 +1711,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra(SettingsActivity.EXTRA_SHOW_HOME_AS_UP, false);
+ intent.putExtra(SettingsActivity.EXTRA_ENTRY_KEY, extraEntryValue);
startActivity(intent);
}
@@ -1732,7 +1739,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
startActivity(intent);
break;
case 1:
- launchSettings();
+ launchSettings(SettingsActivity.EXTRA_ENTRY_VALUE_LONG_PRESS_COMMA);
break;
}
}
@@ -1764,7 +1771,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
dialog.show();
}
- // TODO: can this be removed somehow without breaking the tests?
@UsedForTesting
SuggestedWords getSuggestedWordsForTest() {
// You may not use this method for anything else than debug
diff --git a/java/src/com/android/inputmethod/latin/NgramContext.java b/java/src/com/android/inputmethod/latin/NgramContext.java
index aeeff6126..9682fb8a4 100644
--- a/java/src/com/android/inputmethod/latin/NgramContext.java
+++ b/java/src/com/android/inputmethod/latin/NgramContext.java
@@ -43,6 +43,10 @@ public class NgramContext {
public static final String CONTEXT_SEPARATOR = " ";
+ public static NgramContext getEmptyPrevWordsContext(int maxPrevWordCount) {
+ return new NgramContext(maxPrevWordCount, WordInfo.EMPTY_WORD_INFO);
+ }
+
/**
* Word information used to represent previous words information.
*/
@@ -102,10 +106,17 @@ public class NgramContext {
private final WordInfo[] mPrevWordsInfo;
private final int mPrevWordsCount;
+ private final int mMaxPrevWordCount;
+
// Construct from the previous word information.
public NgramContext(final WordInfo... prevWordsInfo) {
+ this(DecoderSpecificConstants.MAX_PREV_WORD_COUNT_FOR_N_GRAM, prevWordsInfo);
+ }
+
+ public NgramContext(final int maxPrevWordCount, final WordInfo... prevWordsInfo) {
mPrevWordsInfo = prevWordsInfo;
mPrevWordsCount = prevWordsInfo.length;
+ mMaxPrevWordCount = maxPrevWordCount;
}
/**
@@ -113,12 +124,11 @@ public class NgramContext {
*/
@Nonnull
public NgramContext getNextNgramContext(final WordInfo wordInfo) {
- final int nextPrevWordCount = Math.min(
- DecoderSpecificConstants.MAX_PREV_WORD_COUNT_FOR_N_GRAM, mPrevWordsCount + 1);
+ final int nextPrevWordCount = Math.min(mMaxPrevWordCount, mPrevWordsCount + 1);
final WordInfo[] prevWordsInfo = new WordInfo[nextPrevWordCount];
prevWordsInfo[0] = wordInfo;
System.arraycopy(mPrevWordsInfo, 0, prevWordsInfo, 1, nextPrevWordCount - 1);
- return new NgramContext(prevWordsInfo);
+ return new NgramContext(mMaxPrevWordCount, prevWordsInfo);
}
diff --git a/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java b/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java
index c9b6d6b70..e2c562174 100644
--- a/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java
+++ b/java/src/com/android/inputmethod/latin/PunctuationSuggestions.java
@@ -114,7 +114,8 @@ public final class PunctuationSuggestions extends SuggestedWords {
}
private static SuggestedWordInfo newHardCodedWordInfo(final String keySpec) {
- return new SuggestedWordInfo(keySpec, SuggestedWordInfo.MAX_SCORE,
+ return new SuggestedWordInfo(keySpec, "" /* prevWordsContext */,
+ SuggestedWordInfo.MAX_SCORE,
SuggestedWordInfo.KIND_HARDCODED,
Dictionary.DICTIONARY_HARDCODED,
SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
diff --git a/java/src/com/android/inputmethod/latin/RichInputMethodSubtype.java b/java/src/com/android/inputmethod/latin/RichInputMethodSubtype.java
index c7bd88933..9d7849ffc 100644
--- a/java/src/com/android/inputmethod/latin/RichInputMethodSubtype.java
+++ b/java/src/com/android/inputmethod/latin/RichInputMethodSubtype.java
@@ -36,7 +36,8 @@ import javax.annotation.Nullable;
*
* Right now, this returns the extra value of its primary subtype.
*/
-public final class RichInputMethodSubtype {
+// non final for easy mocking.
+public class RichInputMethodSubtype {
private static final String TAG = RichInputMethodSubtype.class.getSimpleName();
@Nonnull
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index 6a0d6be9c..7ccefd2dd 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -19,6 +19,7 @@ package com.android.inputmethod.latin;
import android.text.TextUtils;
import static com.android.inputmethod.latin.define.DecoderSpecificConstants.SHOULD_AUTO_CORRECT_USING_NON_WHITE_LISTED_SUGGESTION;
+import static com.android.inputmethod.latin.define.DecoderSpecificConstants.SHOULD_REMOVE_PREVIOUSLY_REJECTED_SUGGESTION;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
@@ -35,7 +36,6 @@ import java.util.HashMap;
import java.util.Locale;
import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
/**
* This class loads a dictionary and provides a list of suggestions for a given sequence of
@@ -147,18 +147,6 @@ public final class Suggest {
return firstSuggestedWordInfo;
}
- // Quality constants for dictionary match
- // In increasing order of quality
- // This source dictionary does not match the typed word.
- private static final int QUALITY_NO_MATCH = 0;
- // This source dictionary has a null locale, and the preferred locale is also null.
- private static final int QUALITY_MATCH_NULL = 1;
- // This source dictionary has a non-null locale different from the preferred locale. The
- // preferred locale may be null : this is still better than MATCH_NULL.
- private static final int QUALITY_MATCH_OTHER_LOCALE = 2;
- // This source dictionary matches the preferred locale.
- private static final int QUALITY_MATCH_PREFERRED_LOCALE = 3;
-
// Retrieves suggestions for non-batch input (typing, recorrection, predictions...)
// and calls the callback function with the suggestions.
private void getSuggestedWordsForNonBatchInput(final WordComposer wordComposer,
@@ -179,34 +167,18 @@ public final class Suggest {
final Locale locale = mDictionaryFacilitator.getLocale();
final ArrayList<SuggestedWordInfo> suggestionsContainer =
getTransformedSuggestedWordInfoList(wordComposer, suggestionResults,
- trailingSingleQuotesCount,
- // For transforming suggestions that don't come for any dictionary, we
- // use the currently most probable locale as it's our best bet.
- locale);
-
- boolean typedWordExistsInAnotherLanguage = false;
- int qualityOfFoundSourceDictionary = QUALITY_NO_MATCH;
- @Nullable Dictionary sourceDictionaryOfRemovedWord = null;
+ trailingSingleQuotesCount, locale);
+
+ boolean foundInDictionary = false;
+ Dictionary sourceDictionaryOfRemovedWord = null;
for (final SuggestedWordInfo info : suggestionsContainer) {
// Search for the best dictionary, defined as the first one with the highest match
// quality we can find.
- if (typedWordString.equals(info.mWord)) {
- if (locale.equals(info.mSourceDict.mLocale)) {
- if (qualityOfFoundSourceDictionary < QUALITY_MATCH_PREFERRED_LOCALE) {
- // Use this source if the old match had lower quality than this match
- sourceDictionaryOfRemovedWord = info.mSourceDict;
- qualityOfFoundSourceDictionary = QUALITY_MATCH_PREFERRED_LOCALE;
- }
- } else {
- final int matchQuality = (null == info.mSourceDict.mLocale)
- ? QUALITY_MATCH_NULL : QUALITY_MATCH_OTHER_LOCALE;
- if (qualityOfFoundSourceDictionary < matchQuality) {
- // Use this source if the old match had lower quality than this match
- sourceDictionaryOfRemovedWord = info.mSourceDict;
- qualityOfFoundSourceDictionary = matchQuality;
- }
- typedWordExistsInAnotherLanguage = true;
- }
+ if (!foundInDictionary && typedWordString.equals(info.mWord)) {
+ // Use this source if the old match had lower quality than this match
+ sourceDictionaryOfRemovedWord = info.mSourceDict;
+ foundInDictionary = true;
+ break;
}
}
@@ -215,22 +187,8 @@ public final class Suggest {
final SuggestedWordInfo whitelistedWordInfo =
getWhitelistedWordInfoOrNull(suggestionsContainer);
- final String whitelistedWord;
- if (null != whitelistedWordInfo &&
- (mDictionaryFacilitator.isForLocale(whitelistedWordInfo.mSourceDict.mLocale)
- || (!typedWordExistsInAnotherLanguage
- && !hasPlausibleCandidateInAnyOtherLanguage(suggestionsContainer,
- consideredWord, whitelistedWordInfo)))) {
- // We'll use the whitelist candidate if we are confident the user is typing in the
- // language of the dictionary it's coming from, or if there is no plausible candidate
- // coming from another language.
- whitelistedWord = whitelistedWordInfo.mWord;
- } else {
- // If on the contrary we are not confident in the current language and we have
- // at least a plausible candidate in any other language, then we don't use this
- // whitelist candidate.
- whitelistedWord = null;
- }
+ final String whitelistedWord = whitelistedWordInfo == null
+ ? null : whitelistedWordInfo.mWord;
final boolean resultsArePredictions = !wordComposer.isComposingWord();
// We allow auto-correction if whitelisting is not required or the word is whitelisted,
@@ -290,7 +248,8 @@ public final class Suggest {
}
final SuggestedWordInfo typedWordInfo = new SuggestedWordInfo(typedWordString,
- SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_TYPED,
+ "" /* prevWordsContext */, SuggestedWordInfo.MAX_SCORE,
+ SuggestedWordInfo.KIND_TYPED,
null == sourceDictionaryOfRemovedWord ? Dictionary.DICTIONARY_USER_TYPED
: sourceDictionaryOfRemovedWord,
SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
@@ -325,20 +284,6 @@ public final class Suggest {
false /* isObsoleteSuggestions */, inputStyle, sequenceNumber));
}
- private boolean hasPlausibleCandidateInAnyOtherLanguage(
- final ArrayList<SuggestedWordInfo> suggestionsContainer, final String consideredWord,
- final SuggestedWordInfo whitelistedWordInfo) {
- for (final SuggestedWordInfo info : suggestionsContainer) {
- if (whitelistedWordInfo.mSourceDict.mLocale.equals(info.mSourceDict.mLocale)) {
- continue;
- }
- return AutoCorrectionUtils.suggestionExceedsThreshold(info, consideredWord,
- mPlausibilityThreshold);
- }
- // No candidate in another language
- return false;
- }
-
// Retrieves suggestions for the batch input
// and calls the callback function with the suggestions.
private void getSuggestedWordsForBatchInput(final WordComposer wordComposer,
@@ -367,8 +312,10 @@ public final class Suggest {
}
}
- if (suggestionsContainer.size() > 1 && TextUtils.equals(suggestionsContainer.get(0).mWord,
- wordComposer.getRejectedBatchModeSuggestion())) {
+ if (SHOULD_REMOVE_PREVIOUSLY_REJECTED_SUGGESTION
+ && suggestionsContainer.size() > 1
+ && TextUtils.equals(suggestionsContainer.get(0).mWord,
+ wordComposer.getRejectedBatchModeSuggestion())) {
final SuggestedWordInfo rejected = suggestionsContainer.remove(0);
suggestionsContainer.add(1, rejected);
}
@@ -479,7 +426,8 @@ public final class Suggest {
for (int i = quotesToAppend - 1; i >= 0; --i) {
sb.appendCodePoint(Constants.CODE_SINGLE_QUOTE);
}
- return new SuggestedWordInfo(sb.toString(), wordInfo.mScore, wordInfo.mKindAndFlags,
+ return new SuggestedWordInfo(sb.toString(), wordInfo.mPrevWordsContext,
+ wordInfo.mScore, wordInfo.mKindAndFlags,
wordInfo.mSourceDict, wordInfo.mIndexOfTouchPointOfSecondWord,
wordInfo.mAutoCommitFirstWordConfidence);
}
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index 3816c0870..bcd4d5f69 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -17,11 +17,9 @@
package com.android.inputmethod.latin;
import android.text.TextUtils;
-import android.util.Log;
import android.view.inputmethod.CompletionInfo;
import com.android.inputmethod.annotations.UsedForTesting;
-import com.android.inputmethod.latin.common.Constants;
import com.android.inputmethod.latin.common.StringUtils;
import com.android.inputmethod.latin.define.DebugFlags;
@@ -264,12 +262,14 @@ public class SuggestedWords {
public static final int KIND_FLAG_APPROPRIATE_FOR_AUTO_CORRECTION = 0x10000000;
public final String mWord;
+ public final String mPrevWordsContext;
// The completion info from the application. Null for suggestions that don't come from
// the application (including keyboard-computed ones, so this is almost always null)
public final CompletionInfo mApplicationSpecifiedCompletionInfo;
public final int mScore;
public final int mKindAndFlags;
public final int mCodePointCount;
+ @Deprecated
public final Dictionary mSourceDict;
// For auto-commit. This keeps track of the index inside the touch coordinates array
// passed to native code to get suggestions for a gesture that corresponds to the first
@@ -283,6 +283,7 @@ public class SuggestedWords {
/**
* Create a new suggested word info.
* @param word The string to suggest.
+ * @param prevWordsContext previous words context.
* @param score A measure of how likely this suggestion is.
* @param kindAndFlags The kind of suggestion, as one of the above KIND_* constants with
* flags.
@@ -290,10 +291,12 @@ public class SuggestedWords {
* @param indexOfTouchPointOfSecondWord See mIndexOfTouchPointOfSecondWord.
* @param autoCommitFirstWordConfidence See mAutoCommitFirstWordConfidence.
*/
- public SuggestedWordInfo(final String word, final int score, final int kindAndFlags,
+ public SuggestedWordInfo(final String word, final String prevWordsContext,
+ final int score, final int kindAndFlags,
final Dictionary sourceDict, final int indexOfTouchPointOfSecondWord,
final int autoCommitFirstWordConfidence) {
mWord = word;
+ mPrevWordsContext = prevWordsContext;
mApplicationSpecifiedCompletionInfo = null;
mScore = score;
mKindAndFlags = kindAndFlags;
@@ -310,6 +313,7 @@ public class SuggestedWords {
*/
public SuggestedWordInfo(final CompletionInfo applicationSpecifiedCompletion) {
mWord = applicationSpecifiedCompletion.getText().toString();
+ mPrevWordsContext = "";
mApplicationSpecifiedCompletionInfo = applicationSpecifiedCompletion;
mScore = SuggestedWordInfo.MAX_SCORE;
mKindAndFlags = SuggestedWordInfo.KIND_APP_DEFINED;
@@ -360,6 +364,7 @@ public class SuggestedWords {
return mWord;
}
+ @Deprecated
public Dictionary getSourceDictionary() {
return mSourceDict;
}
@@ -427,27 +432,6 @@ public class SuggestedWords {
return isPrediction(mInputStyle);
}
- // Creates a new SuggestedWordInfo from the currently suggested words that removes all but the
- // last word of all suggestions, separated by a space. This is necessary because when we commit
- // a multiple-word suggestion, the IME only retains the last word as the composing word, and
- // we should only suggest replacements for this last word.
- // TODO: make this work with languages without spaces.
- public SuggestedWords getSuggestedWordsForLastWordOfPhraseGesture() {
- final ArrayList<SuggestedWordInfo> newSuggestions = new ArrayList<>();
- for (int i = 0; i < mSuggestedWordInfoList.size(); ++i) {
- final SuggestedWordInfo info = mSuggestedWordInfoList.get(i);
- final int indexOfLastSpace = info.mWord.lastIndexOf(Constants.CODE_SPACE) + 1;
- final String lastWord = info.mWord.substring(indexOfLastSpace);
- newSuggestions.add(new SuggestedWordInfo(lastWord, info.mScore, info.mKindAndFlags,
- info.mSourceDict, SuggestedWordInfo.NOT_AN_INDEX,
- SuggestedWordInfo.NOT_A_CONFIDENCE));
- }
- return new SuggestedWords(newSuggestions, null /* rawSuggestions */,
- newSuggestions.isEmpty() ? null : newSuggestions.get(0) /* typedWordInfo */,
- mTypedWordValid, mWillAutoCorrect, mIsObsoleteSuggestions, INPUT_STYLE_TAIL_BATCH,
- NOT_A_SEQUENCE_NUMBER);
- }
-
/**
* @return the {@link SuggestedWordInfo} which corresponds to the word that is originally
* typed by the user. Otherwise returns {@code null}. Note that gesture input is not
diff --git a/java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java b/java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java
deleted file mode 100644
index 8cc3552ed..000000000
--- a/java/src/com/android/inputmethod/latin/debug/ExternalDictionaryGetterForDebug.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.inputmethod.latin.debug;
-
-import android.app.AlertDialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnCancelListener;
-import android.content.DialogInterface.OnClickListener;
-import android.os.Environment;
-
-import com.android.inputmethod.latin.BinaryDictionaryFileDumper;
-import com.android.inputmethod.latin.BinaryDictionaryGetter;
-import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.common.LocaleUtils;
-import com.android.inputmethod.latin.makedict.DictionaryHeader;
-import com.android.inputmethod.latin.utils.DialogUtils;
-import com.android.inputmethod.latin.utils.DictionaryInfoUtils;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Locale;
-
-/**
- * A class to read a local file as a dictionary for debugging purposes.
- */
-public class ExternalDictionaryGetterForDebug {
- static final String SOURCE_FOLDER = Environment.getExternalStorageDirectory().getPath()
- + "/Download";
-
- private static String[] findDictionariesInTheDownloadedFolder() {
- final File[] files = new File(SOURCE_FOLDER).listFiles();
- final ArrayList<String> eligibleList = new ArrayList<>();
- for (File f : files) {
- final DictionaryHeader header = DictionaryInfoUtils.getDictionaryFileHeaderOrNull(f);
- if (null == header) continue;
- eligibleList.add(f.getName());
- }
- return eligibleList.toArray(new String[0]);
- }
-
- public static void chooseAndInstallDictionary(final Context context) {
- final String[] fileNames = findDictionariesInTheDownloadedFolder();
- if (0 == fileNames.length) {
- showNoFileDialog(context);
- } else if (1 == fileNames.length) {
- askInstallFile(context, SOURCE_FOLDER, fileNames[0], null /* completeRunnable */);
- } else {
- showChooseFileDialog(context, fileNames);
- }
- }
-
- private static void showNoFileDialog(final Context context) {
- new AlertDialog.Builder(DialogUtils.getPlatformDialogThemeContext(context))
- .setMessage(R.string.read_external_dictionary_no_files_message)
- .setPositiveButton(android.R.string.ok, new OnClickListener() {
- @Override
- public void onClick(final DialogInterface dialog, final int which) {
- dialog.dismiss();
- }
- }).create().show();
- }
-
- private static void showChooseFileDialog(final Context context, final String[] fileNames) {
- new AlertDialog.Builder(DialogUtils.getPlatformDialogThemeContext(context))
- .setTitle(R.string.read_external_dictionary_multiple_files_title)
- .setItems(fileNames, new OnClickListener() {
- @Override
- public void onClick(final DialogInterface dialog, final int which) {
- askInstallFile(context, SOURCE_FOLDER, fileNames[which],
- null /* completeRunnable */);
- }
- })
- .create().show();
- }
-
- /**
- * Shows a dialog which offers the user to install the external dictionary.
- */
- public static void askInstallFile(final Context context, final String dirPath,
- final String fileName, final Runnable completeRunnable) {
- final File file = new File(dirPath, fileName.toString());
- final DictionaryHeader header = DictionaryInfoUtils.getDictionaryFileHeaderOrNull(file);
- final StringBuilder message = new StringBuilder();
- final String localeString = header.mLocaleString;
- for (final String key : header.mDictionaryOptions.mAttributes.keySet()) {
- message.append(key + " = " + header.mDictionaryOptions.mAttributes.get(key));
- message.append("\n");
- }
- final String languageName = LocaleUtils.constructLocaleFromString(localeString)
- .getDisplayName(Locale.getDefault());
- final String title = String.format(
- context.getString(R.string.read_external_dictionary_confirm_install_message),
- languageName);
- new AlertDialog.Builder(DialogUtils.getPlatformDialogThemeContext(context))
- .setTitle(title)
- .setMessage(message)
- .setNegativeButton(android.R.string.cancel, new OnClickListener() {
- @Override
- public void onClick(final DialogInterface dialog, final int which) {
- dialog.dismiss();
- if (completeRunnable != null) {
- completeRunnable.run();
- }
- }
- }).setPositiveButton(android.R.string.ok, new OnClickListener() {
- @Override
- public void onClick(final DialogInterface dialog, final int which) {
- installFile(context, file, header);
- dialog.dismiss();
- if (completeRunnable != null) {
- completeRunnable.run();
- }
- }
- }).setOnCancelListener(new OnCancelListener() {
- @Override
- public void onCancel(DialogInterface dialog) {
- // Canceled by the user by hitting the back key
- if (completeRunnable != null) {
- completeRunnable.run();
- }
- }
- }).create().show();
- }
-
- static void installFile(final Context context, final File file, final DictionaryHeader header) {
- BufferedOutputStream outputStream = null;
- File tempFile = null;
- try {
- final String localeString = header.mLocaleString;
- // Create the id for a main dictionary for this locale
- final String id = BinaryDictionaryGetter.MAIN_DICTIONARY_CATEGORY
- + BinaryDictionaryGetter.ID_CATEGORY_SEPARATOR + localeString;
- final String finalFileName = DictionaryInfoUtils.getCacheFileName(
- id, localeString, context);
- final String tempFileName = BinaryDictionaryGetter.getTempFileName(id, context);
- tempFile = new File(tempFileName);
- tempFile.delete();
- outputStream = new BufferedOutputStream(new FileOutputStream(tempFile));
- final BufferedInputStream bufferedStream = new BufferedInputStream(
- new FileInputStream(file));
- BinaryDictionaryFileDumper.checkMagicAndCopyFileTo(bufferedStream, outputStream);
- outputStream.flush();
- final File finalFile = new File(finalFileName);
- finalFile.delete();
- if (!tempFile.renameTo(finalFile)) {
- throw new IOException("Can't move the file to its final name");
- }
- } catch (IOException e) {
- // There was an error: show a dialog
- new AlertDialog.Builder(DialogUtils.getPlatformDialogThemeContext(context))
- .setTitle(R.string.read_external_dictionary_error)
- .setMessage(e.toString())
- .setPositiveButton(android.R.string.ok, new OnClickListener() {
- @Override
- public void onClick(final DialogInterface dialog, final int which) {
- dialog.dismiss();
- }
- }).create().show();
- return;
- } finally {
- try {
- if (null != outputStream) outputStream.close();
- if (null != tempFile) tempFile.delete();
- } catch (IOException e) {
- // Don't do anything
- }
- }
- }
-}
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index f3840f74e..5b3b28d75 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -225,9 +225,7 @@ public final class InputLogic {
* @return the complete transaction object
*/
public InputTransaction onTextInput(final SettingsValues settingsValues, final Event event,
- final int keyboardShiftMode,
- // TODO: remove this argument
- final LatinIME.UIHandler handler) {
+ final int keyboardShiftMode, final LatinIME.UIHandler handler) {
final String rawText = event.getTextToCommit().toString();
final InputTransaction inputTransaction = new InputTransaction(settingsValues, event,
SystemClock.uptimeMillis(), mSpaceState,
@@ -266,12 +264,14 @@ public final class InputLogic {
// interface
public InputTransaction onPickSuggestionManually(final SettingsValues settingsValues,
final SuggestedWordInfo suggestionInfo, final int keyboardShiftState,
- // TODO: remove these arguments
final int currentKeyboardScriptId, final LatinIME.UIHandler handler) {
final SuggestedWords suggestedWords = mSuggestedWords;
final String suggestion = suggestionInfo.mWord;
// If this is a punctuation picked from the suggestion strip, pass it to onCodeInput
if (suggestion.length() == 1 && suggestedWords.isPunctuationSuggestions()) {
+ // We still want to log a suggestion click.
+ StatsUtils.onPickSuggestionManually(
+ mSuggestedWords, suggestionInfo, mDictionaryFacilitator);
// Word separators are suggested before the user inputs something.
// Rely on onCodeInput to do the complicated swapping/stripping logic consistently.
final Event event = Event.createPunctuationSuggestionPickedEvent(suggestionInfo);
@@ -324,7 +324,8 @@ public final class InputLogic {
// That's going to be predictions (or punctuation suggestions), so INPUT_STYLE_NONE.
handler.postUpdateSuggestionStrip(SuggestedWords.INPUT_STYLE_NONE);
- StatsUtils.onPickSuggestionManually(mSuggestedWords, suggestionInfo);
+ StatsUtils.onPickSuggestionManually(
+ mSuggestedWords, suggestionInfo, mDictionaryFacilitator);
StatsUtils.onWordCommitSuggestionPickedManually(
suggestionInfo.mWord, mWordComposer.isBatchMode());
return inputTransaction;
@@ -418,7 +419,6 @@ public final class InputLogic {
*/
public InputTransaction onCodeInput(final SettingsValues settingsValues,
@Nonnull final Event event, final int keyboardShiftMode,
- // TODO: remove these arguments
final int currentKeyboardScriptId, final LatinIME.UIHandler handler) {
final Event processedEvent = mWordComposer.processEvent(event);
final InputTransaction inputTransaction = new InputTransaction(settingsValues,
@@ -465,7 +465,6 @@ public final class InputLogic {
}
public void onStartBatchInput(final SettingsValues settingsValues,
- // TODO: remove these arguments
final KeyboardSwitcher keyboardSwitcher, final LatinIME.UIHandler handler) {
mInputLogicHandler.onStartBatchInput();
handler.showGesturePreviewAndSuggestionStrip(
@@ -529,10 +528,7 @@ public final class InputLogic {
* earlier sequence number.
*/
private int mAutoCommitSequenceNumber = 1;
- public void onUpdateBatchInput(final SettingsValues settingsValues,
- final InputPointers batchPointers,
- // TODO: remove these arguments
- final KeyboardSwitcher keyboardSwitcher) {
+ public void onUpdateBatchInput(final InputPointers batchPointers) {
mInputLogicHandler.onUpdateBatchInput(batchPointers, mAutoCommitSequenceNumber);
}
@@ -541,7 +537,6 @@ public final class InputLogic {
++mAutoCommitSequenceNumber;
}
- // TODO: remove this argument
public void onCancelBatchInput(final LatinIME.UIHandler handler) {
mInputLogicHandler.onCancelBatchInput();
handler.showGesturePreviewAndSuggestionStrip(
@@ -617,7 +612,6 @@ public final class InputLogic {
* @param inputTransaction The transaction in progress.
*/
private void handleFunctionalEvent(final Event event, final InputTransaction inputTransaction,
- // TODO: remove these arguments
final int currentKeyboardScriptId, final LatinIME.UIHandler handler) {
switch (event.mKeyCode) {
case Constants.CODE_DELETE:
@@ -669,7 +663,6 @@ public final class InputLogic {
// handled in {@link KeyboardState#onEvent(Event,int)}.
break;
case Constants.CODE_SHIFT_ENTER:
- // TODO: remove this object
final Event tmpEvent = Event.createSoftwareKeypressEvent(Constants.CODE_ENTER,
event.mKeyCode, event.mX, event.mY, event.isKeyRepeat());
handleNonSpecialCharacterEvent(tmpEvent, inputTransaction, handler);
@@ -693,7 +686,6 @@ public final class InputLogic {
*/
private void handleNonFunctionalEvent(final Event event,
final InputTransaction inputTransaction,
- // TODO: remove this argument
final LatinIME.UIHandler handler) {
inputTransaction.setDidAffectContents();
switch (event.mCodePoint) {
@@ -739,7 +731,6 @@ public final class InputLogic {
*/
private void handleNonSpecialCharacterEvent(final Event event,
final InputTransaction inputTransaction,
- // TODO: remove this argument
final LatinIME.UIHandler handler) {
final int codePoint = event.mCodePoint;
mSpaceState = SpaceState.NONE;
@@ -845,7 +836,6 @@ public final class InputLogic {
* @param inputTransaction The transaction in progress.
*/
private void handleSeparatorEvent(final Event event, final InputTransaction inputTransaction,
- // TODO: remove this argument
final LatinIME.UIHandler handler) {
final int codePoint = event.mCodePoint;
final SettingsValues settingsValues = inputTransaction.mSettingsValues;
@@ -953,7 +943,6 @@ public final class InputLogic {
* @param inputTransaction The transaction in progress.
*/
private void handleBackspaceEvent(final Event event, final InputTransaction inputTransaction,
- // TODO: remove this argument, put it into settingsValues
final int currentKeyboardScriptId) {
mSpaceState = SpaceState.NONE;
mDeleteCount++;
@@ -1157,7 +1146,6 @@ public final class InputLogic {
settingsValues.mSpacingAndPunctuations,
currentKeyboardScriptId);
if (range == null) {
- // TODO(zivkovic): Check for bad connection before getting this far.
// Happens if we don't have an input connection at all.
return false;
}
@@ -1395,6 +1383,11 @@ public final class InputLogic {
return;
}
+ if (!mWordComposer.isComposingWord() && !settingsValues.mBigramPredictionEnabled) {
+ mSuggestionStripViewAccessor.setNeutralSuggestionStrip();
+ return;
+ }
+
final AsyncResultHolder<SuggestedWords> holder = new AsyncResultHolder<>();
mInputLogicHandler.getSuggestedWords(inputStyle, SuggestedWords.NOT_A_SEQUENCE_NUMBER,
new OnGetSuggestedWordsCallback() {
@@ -1402,7 +1395,8 @@ public final class InputLogic {
public void onGetSuggestedWords(final SuggestedWords suggestedWords) {
final String typedWordString = mWordComposer.getTypedWord();
final SuggestedWordInfo typedWordInfo = new SuggestedWordInfo(
- typedWordString, SuggestedWordInfo.MAX_SCORE,
+ typedWordString, "" /* prevWordsContext */,
+ SuggestedWordInfo.MAX_SCORE,
SuggestedWordInfo.KIND_TYPED, Dictionary.DICTIONARY_USER_TYPED,
SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
SuggestedWordInfo.NOT_A_CONFIDENCE);
@@ -1435,7 +1429,6 @@ public final class InputLogic {
* to a cursor move, for example). In ICS, there is a platform bug that we need to work
* around only when we come here at input start time.
*/
- // TODO: make this private.
public void restartSuggestionsOnWordTouchedByCursor(final SettingsValues settingsValues,
final boolean forStartInput,
// TODO: remove this argument, put it into settingsValues
@@ -1486,7 +1479,7 @@ public final class InputLogic {
final ArrayList<SuggestedWordInfo> suggestions = new ArrayList<>();
final String typedWordString = range.mWord.toString();
final SuggestedWordInfo typedWordInfo = new SuggestedWordInfo(typedWordString,
- SuggestedWords.MAX_SUGGESTIONS + 1,
+ "" /* prevWordsContext */, SuggestedWords.MAX_SUGGESTIONS + 1,
SuggestedWordInfo.KIND_TYPED, Dictionary.DICTIONARY_USER_TYPED,
SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */);
@@ -1501,7 +1494,7 @@ public final class InputLogic {
++i;
if (!TextUtils.equals(s, typedWordString)) {
suggestions.add(new SuggestedWordInfo(s,
- SuggestedWords.MAX_SUGGESTIONS - i,
+ "" /* prevWordsContext */, SuggestedWords.MAX_SUGGESTIONS - i,
SuggestedWordInfo.KIND_RESUMED, Dictionary.DICTIONARY_RESUMED,
SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
SuggestedWordInfo.NOT_A_CONFIDENCE
@@ -1602,15 +1595,11 @@ public final class InputLogic {
// First, add the committed word to the list of suggestions.
suggestions.add(committedWordString);
for (final Object span : spans) {
- // If this is a suggestion span, we check that the locale is the right one, and
- // that the word is not the committed word. That should mostly be the case.
+ // If this is a suggestion span, we check that the word is not the committed word.
+ // That should mostly be the case.
// Given this, we add it to the list of suggestions, otherwise we discard it.
if (span instanceof SuggestionSpan) {
final SuggestionSpan suggestionSpan = (SuggestionSpan)span;
- if (!suggestionSpan.getLocale().equals(
- inputTransaction.mSettingsValues.mLocale.toString())) {
- continue;
- }
for (final String suggestion : suggestionSpan.getSuggestions()) {
if (!suggestion.equals(committedWordString)) {
suggestions.add(suggestion);
@@ -1719,7 +1708,6 @@ public final class InputLogic {
* @param nthPreviousWord reverse index of the word to get (1-indexed)
* @return the information of previous words
*/
- // TODO: Make this private
public NgramContext getNgramContextFromNthPreviousWordForSuggestion(
final SpacingAndPunctuations spacingAndPunctuations, final int nthPreviousWord) {
if (spacingAndPunctuations.mCurrentLanguageHasSpaces) {
@@ -1949,9 +1937,7 @@ public final class InputLogic {
* @param suggestedWords suggestedWords to use.
*/
public void onUpdateTailBatchInputCompleted(final SettingsValues settingsValues,
- final SuggestedWords suggestedWords,
- // TODO: remove this argument
- final KeyboardSwitcher keyboardSwitcher) {
+ final SuggestedWords suggestedWords, final KeyboardSwitcher keyboardSwitcher) {
final String batchInputText = suggestedWords.isEmpty() ? null : suggestedWords.getWord(0);
if (TextUtils.isEmpty(batchInputText)) {
return;
@@ -1984,7 +1970,6 @@ public final class InputLogic {
* @param settingsValues the current values of the settings.
* @param separatorString the separator that's causing the commit, or NOT_A_SEPARATOR if none.
*/
- // TODO: Make this private
public void commitTyped(final SettingsValues settingsValues, final String separatorString) {
if (!mWordComposer.isComposingWord()) return;
final String typedWord = mWordComposer.getTypedWord();
@@ -2013,9 +1998,7 @@ public final class InputLogic {
* @param separator the separator that's causing the commit to happen.
*/
private void commitCurrentAutoCorrection(final SettingsValues settingsValues,
- final String separator,
- // TODO: Remove this argument.
- final LatinIME.UIHandler handler) {
+ final String separator, final LatinIME.UIHandler handler) {
// Complete any pending suggestions query first
if (handler.hasPendingUpdateSuggestions()) {
handler.cancelUpdateSuggestionStrip();
@@ -2051,9 +2034,11 @@ public final class InputLogic {
mConnection.commitCorrection(new CorrectionInfo(
mConnection.getExpectedSelectionEnd() - stringToCommit.length(),
typedWord, stringToCommit));
+ String prevWordsContext = (autoCorrectionOrNull != null)
+ ? autoCorrectionOrNull.mPrevWordsContext
+ : "";
StatsUtils.onAutoCorrection(typedWord, stringToCommit, isBatchMode,
- null == autoCorrectionOrNull
- ? null : autoCorrectionOrNull.mSourceDict.mDictType);
+ mDictionaryFacilitator, prevWordsContext);
StatsUtils.onWordCommitAutoCorrect(stringToCommit, isBatchMode);
} else {
StatsUtils.onWordCommitUserTyped(stringToCommit, isBatchMode);
@@ -2102,11 +2087,8 @@ public final class InputLogic {
* @param remainingTries How many times we may try again before giving up.
* @return whether true if the caches were successfully reset, false otherwise.
*/
- // TODO: make this private
public boolean retryResetCachesAndReturnSuccess(final boolean tryResumeSuggestions,
- final int remainingTries,
- // TODO: remove these arguments
- final LatinIME.UIHandler handler) {
+ final int remainingTries, final LatinIME.UIHandler handler) {
final boolean shouldFinishComposition = mConnection.hasSelection()
|| !mConnection.isCursorPositionKnown();
if (!mConnection.resetCachesUponCursorMoveAndReturnSuccess(
diff --git a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
index 32a746d37..e422c4cd2 100644
--- a/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
+++ b/java/src/com/android/inputmethod/latin/makedict/FormatSpec.java
@@ -174,17 +174,13 @@ public final class FormatSpec {
public static final int VERSION202 = 202;
// format version for Fava Dictionaries.
public static final int VERSION_DELIGHT3 = 86736212;
- public static final int MINIMUM_SUPPORTED_VERSION_OF_CODE_POINT_TABLE = VERSION201;
- // Dictionary version used for testing.
- public static final int VERSION4_ONLY_FOR_TESTING = 399;
public static final int VERSION402 = 402;
public static final int VERSION403 = 403;
public static final int VERSION4 = VERSION403;
- public static final int VERSION4_DEV = VERSION403;
public static final int MINIMUM_SUPPORTED_STATIC_VERSION = VERSION202;
public static final int MAXIMUM_SUPPORTED_STATIC_VERSION = VERSION_DELIGHT3;
static final int MINIMUM_SUPPORTED_DYNAMIC_VERSION = VERSION4;
- static final int MAXIMUM_SUPPORTED_DYNAMIC_VERSION = VERSION4_DEV;
+ static final int MAXIMUM_SUPPORTED_DYNAMIC_VERSION = VERSION403;
// TODO: Make this value adaptative to content data, store it in the header, and
// use it in the reading code.
diff --git a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java
index 54ee68d65..cbf0829b5 100644
--- a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java
@@ -20,6 +20,7 @@ import android.content.Context;
import com.android.inputmethod.annotations.ExternallyReferenced;
import com.android.inputmethod.annotations.UsedForTesting;
+import com.android.inputmethod.latin.BinaryDictionary;
import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.ExpandableBinaryDictionary;
import com.android.inputmethod.latin.NgramContext;
@@ -98,7 +99,7 @@ public class UserHistoryDictionary extends ExpandableBinaryDictionary {
public static void addToDictionary(final ExpandableBinaryDictionary userHistoryDictionary,
@Nonnull final NgramContext ngramContext, final String word, final boolean isValid,
final int timestamp) {
- if (word.length() > DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH) {
+ if (word.length() > BinaryDictionary.DICTIONARY_MAX_WORD_LENGTH) {
return;
}
userHistoryDictionary.updateEntriesForWord(ngramContext, word,
diff --git a/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java
index 9a8a7b9e0..48361bf8c 100644
--- a/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/AccountsSettingsFragment.java
@@ -27,16 +27,13 @@ import android.content.SharedPreferences;
import android.content.res.Resources;
import android.os.AsyncTask;
import android.os.Bundle;
-import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
-import android.preference.SwitchPreference;
import android.preference.TwoStatePreference;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
import android.widget.ListView;
import android.widget.TextView;
-import android.widget.Toast;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.R;
@@ -122,24 +119,34 @@ public final class AccountsSettingsFragment extends SubScreenFragment {
removeSyncPreferences();
} else {
disableSyncPreferences();
- final AsyncTask<Void, Void, Void> checkManagedProfileTask =
- new AsyncTask<Void, Void, Void>() {
- @Override
- protected Void doInBackground(Void... params) {
- if (ManagedProfileUtils.hasManagedWorkProfile(getActivity())) {
- removeSyncPreferences();
- } else {
- enableSyncPreferences();
- }
- return null;
- }
- };
- checkManagedProfileTask.execute();
+ new ManagedProfileCheckerTask(this).execute();
+ }
+ }
+
+ private static class ManagedProfileCheckerTask extends AsyncTask<Void, Void, Void> {
+ private final AccountsSettingsFragment mFragment;
+
+ private ManagedProfileCheckerTask(final AccountsSettingsFragment fragment) {
+ mFragment = fragment;
+ }
+
+ @Override
+ protected Void doInBackground(Void... params) {
+ if (ManagedProfileUtils.getInstance().hasManagedWorkProfile(mFragment.getActivity())) {
+ mFragment.removeSyncPreferences();
+ } else {
+ mFragment.enableSyncPreferences();
+ }
+ return null;
}
}
private void enableSyncPreferences() {
mAccountSwitcher = findPreference(PREF_ACCCOUNT_SWITCHER);
+ if (mAccountSwitcher == null) {
+ // Preference has been removed because the device has a managed profile.
+ return;
+ }
mAccountSwitcher.setEnabled(true);
mEnableSyncPreference = (TwoStatePreference) findPreference(PREF_ENABLE_SYNC_NOW);
@@ -157,6 +164,10 @@ public final class AccountsSettingsFragment extends SubScreenFragment {
private void disableSyncPreferences() {
mAccountSwitcher = findPreference(PREF_ACCCOUNT_SWITCHER);
+ if (mAccountSwitcher == null) {
+ // Preference has been removed because the device has a managed profile.
+ return;
+ }
mAccountSwitcher.setEnabled(false);
mEnableSyncPreference = (TwoStatePreference) findPreference(PREF_ENABLE_SYNC_NOW);
@@ -214,6 +225,9 @@ public final class AccountsSettingsFragment extends SubScreenFragment {
if (accountsForLogin.length > 0) {
enableSyncPreferences();
+ if (mAccountSwitcher == null) {
+ return;
+ }
mAccountSwitcher.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(final Preference preference) {
diff --git a/java/src/com/android/inputmethod/latin/settings/CorrectionSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/CorrectionSettingsFragment.java
index 44c47fdfa..f7c5f6760 100644
--- a/java/src/com/android/inputmethod/latin/settings/CorrectionSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/CorrectionSettingsFragment.java
@@ -19,11 +19,13 @@ package com.android.inputmethod.latin.settings;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Build;
import android.os.Bundle;
import android.preference.Preference;
+import android.preference.TwoStatePreference;
import com.android.inputmethod.dictionarypack.DictionarySettingsActivity;
import com.android.inputmethod.latin.R;
@@ -59,6 +61,8 @@ public final class CorrectionSettingsFragment extends SubScreenFragment {
final Context context = getActivity();
final PackageManager pm = context.getPackageManager();
+ ensureConsistencyOfAutoCorrectionSettings();
+
final Preference dictionaryLink = findPreference(Settings.PREF_CONFIGURE_DICTIONARIES_KEY);
final Intent intent = dictionaryLink.getIntent();
intent.setClassName(context.getPackageName(), DictionarySettingsActivity.class.getName());
@@ -78,6 +82,19 @@ public final class CorrectionSettingsFragment extends SubScreenFragment {
}
}
+ @Override
+ public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) {
+ ensureConsistencyOfAutoCorrectionSettings();
+ }
+
+ private void ensureConsistencyOfAutoCorrectionSettings() {
+ final TwoStatePreference autoCorrectionPref = (TwoStatePreference)
+ findPreference(Settings.PREF_AUTO_CORRECTION);
+ if (!autoCorrectionPref.isChecked()) {
+ setPreferenceEnabled(Settings.PREF_BIGRAM_PREDICTIONS, false);
+ }
+ }
+
private void overwriteUserDictionaryPreference(final Preference userDictionaryPreference) {
final Activity activity = getActivity();
final TreeSet<String> localeList = UserDictionaryList.getUserDictionaryLocalesSet(activity);
diff --git a/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java
index a56de1f69..37855377d 100644
--- a/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/DebugSettingsFragment.java
@@ -30,7 +30,6 @@ import android.preference.TwoStatePreference;
import com.android.inputmethod.latin.DictionaryDumpBroadcastReceiver;
import com.android.inputmethod.latin.DictionaryFacilitatorImpl;
import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.debug.ExternalDictionaryGetterForDebug;
import com.android.inputmethod.latin.utils.ApplicationUtils;
import com.android.inputmethod.latin.utils.ResourceUtils;
@@ -43,12 +42,10 @@ import java.util.Locale;
*/
public final class DebugSettingsFragment extends SubScreenFragment
implements OnPreferenceClickListener {
- private static final String PREF_READ_EXTERNAL_DICTIONARY = "read_external_dictionary";
private static final String PREF_KEY_DUMP_DICTS = "pref_key_dump_dictionaries";
private static final String PREF_KEY_DUMP_DICT_PREFIX = "pref_key_dump_dictionaries";
private boolean mServiceNeedsRestart = false;
- private Preference mReadExternalDictionaryPref;
private TwoStatePreference mDebugMode;
@Override
@@ -60,11 +57,6 @@ public final class DebugSettingsFragment extends SubScreenFragment
removePreference(DebugSettings.PREF_SHOULD_SHOW_LXX_SUGGESTION_UI);
}
- mReadExternalDictionaryPref = findPreference(PREF_READ_EXTERNAL_DICTIONARY);
- if (mReadExternalDictionaryPref != null) {
- mReadExternalDictionaryPref.setOnPreferenceClickListener(this);
- }
-
final PreferenceGroup dictDumpPreferenceGroup =
(PreferenceGroup)findPreference(PREF_KEY_DUMP_DICTS);
for (final String dictName : DictionaryFacilitatorImpl.DICT_TYPE_TO_CLASS.keySet()) {
@@ -111,11 +103,6 @@ public final class DebugSettingsFragment extends SubScreenFragment
@Override
public boolean onPreferenceClick(final Preference pref) {
final Context context = getActivity();
- if (pref == mReadExternalDictionaryPref) {
- ExternalDictionaryGetterForDebug.chooseAndInstallDictionary(context);
- mServiceNeedsRestart = true;
- return true;
- }
if (pref instanceof DictDumpPreference) {
final DictDumpPreference dictDumpPref = (DictDumpPreference)pref;
final String dictName = dictDumpPref.mDictName;
diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java
index 5596c7fe9..715f7bb38 100644
--- a/java/src/com/android/inputmethod/latin/settings/Settings.java
+++ b/java/src/com/android/inputmethod/latin/settings/Settings.java
@@ -57,7 +57,10 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
public static final String PREF_VOICE_INPUT_KEY = "pref_voice_input_key";
public static final String PREF_EDIT_PERSONAL_DICTIONARY = "edit_personal_dictionary";
public static final String PREF_CONFIGURE_DICTIONARIES_KEY = "configure_dictionaries_key";
- public static final String PREF_AUTO_CORRECTION_THRESHOLD = "auto_correction_threshold";
+ // PREF_AUTO_CORRECTION_THRESHOLD_OBSOLETE is obsolete. Use PREF_AUTO_CORRECTION instead.
+ public static final String PREF_AUTO_CORRECTION_THRESHOLD_OBSOLETE =
+ "auto_correction_threshold";
+ public static final String PREF_AUTO_CORRECTION = "pref_key_auto_correction";
// PREF_SHOW_SUGGESTIONS_SETTING_OBSOLETE is obsolete. Use PREF_SHOW_SUGGESTIONS instead.
public static final String PREF_SHOW_SUGGESTIONS_SETTING_OBSOLETE = "show_suggestions_setting";
public static final String PREF_SHOW_SUGGESTIONS = "show_suggestions";
@@ -80,6 +83,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
// TODO: consolidate key preview dismiss delay with the key preview animation parameters.
public static final String PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY =
"pref_key_preview_popup_dismiss_delay";
+ public static final String PREF_BIGRAM_PREDICTIONS = "next_word_prediction";
public static final String PREF_GESTURE_INPUT = "gesture_input";
public static final String PREF_VIBRATION_DURATION_SETTINGS =
"pref_vibration_duration_settings";
@@ -139,6 +143,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
mRes = context.getResources();
mPrefs = PreferenceManager.getDefaultSharedPreferences(context);
mPrefs.registerOnSharedPreferenceChangeListener(this);
+ upgradeAutocorrectionSettings(mPrefs, mRes);
}
public void onDestroy() {
@@ -207,11 +212,9 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
res.getBoolean(R.bool.config_default_vibration_enabled));
}
- public static boolean readAutoCorrectEnabled(final String currentAutoCorrectionSetting,
+ public static boolean readAutoCorrectEnabled(final SharedPreferences prefs,
final Resources res) {
- final String autoCorrectionOff = res.getString(
- R.string.auto_correction_threshold_mode_index_off);
- return !currentAutoCorrectionSetting.equals(autoCorrectionOff);
+ return prefs.getBoolean(PREF_AUTO_CORRECTION, true);
}
public static float readPlausibilityThreshold(final Resources res) {
@@ -421,4 +424,21 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
final SharedPreferences prefs, final int defValue) {
return prefs.getInt(PREF_LAST_SHOWN_EMOJI_CATEGORY_ID, defValue);
}
+
+ private void upgradeAutocorrectionSettings(final SharedPreferences prefs, final Resources res) {
+ final String thresholdSetting =
+ prefs.getString(PREF_AUTO_CORRECTION_THRESHOLD_OBSOLETE, null);
+ if (thresholdSetting != null) {
+ SharedPreferences.Editor editor = prefs.edit();
+ editor.remove(PREF_AUTO_CORRECTION_THRESHOLD_OBSOLETE);
+ final String autoCorrectionOff =
+ res.getString(R.string.auto_correction_threshold_mode_index_off);
+ if (thresholdSetting.equals(autoCorrectionOff)) {
+ editor.putBoolean(PREF_AUTO_CORRECTION, false);
+ } else {
+ editor.putBoolean(PREF_AUTO_CORRECTION, true);
+ }
+ editor.commit();
+ }
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsActivity.java b/java/src/com/android/inputmethod/latin/settings/SettingsActivity.java
index b0c494098..dee4811c9 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsActivity.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsActivity.java
@@ -17,6 +17,8 @@
package com.android.inputmethod.latin.settings;
import com.android.inputmethod.latin.utils.FragmentUtils;
+import com.android.inputmethod.latin.utils.StatsUtils;
+import com.android.inputmethod.latin.utils.StatsUtilsManager;
import android.app.ActionBar;
import android.content.Intent;
@@ -25,19 +27,30 @@ import android.preference.PreferenceActivity;
import android.view.MenuItem;
public final class SettingsActivity extends PreferenceActivity {
- public static final String EXTRA_SHOW_HOME_AS_UP = "show_home_as_up";
private static final String DEFAULT_FRAGMENT = SettingsFragment.class.getName();
+
+ public static final String EXTRA_SHOW_HOME_AS_UP = "show_home_as_up";
+ public static final String EXTRA_ENTRY_KEY = "entry";
+ public static final String EXTRA_ENTRY_VALUE_LONG_PRESS_COMMA = "long_press_comma";
+ public static final String EXTRA_ENTRY_VALUE_APP_ICON = "app_icon";
+ public static final String EXTRA_ENTRY_VALUE_NOTICE_DIALOG = "important_notice";
+ public static final String EXTRA_ENTRY_VALUE_SYSTEM_SETTINGS = "system_settings";
+
private boolean mShowHomeAsUp;
@Override
protected void onCreate(final Bundle savedState) {
super.onCreate(savedState);
final ActionBar actionBar = getActionBar();
+ final Intent intent = getIntent();
if (actionBar != null) {
- mShowHomeAsUp = getIntent().getBooleanExtra(EXTRA_SHOW_HOME_AS_UP, true);
+ mShowHomeAsUp = intent.getBooleanExtra(EXTRA_SHOW_HOME_AS_UP, true);
actionBar.setDisplayHomeAsUpEnabled(mShowHomeAsUp);
actionBar.setHomeButtonEnabled(mShowHomeAsUp);
}
+ StatsUtils.onSettingsActivity(
+ intent.hasExtra(EXTRA_ENTRY_KEY) ? intent.getStringExtra(EXTRA_ENTRY_KEY)
+ : intent.getStringExtra(EXTRA_ENTRY_VALUE_SYSTEM_SETTINGS));
}
@Override
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
index ed11de96e..d112e7200 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
@@ -73,12 +73,15 @@ public class SettingsValues {
public final boolean mUsePersonalizedDicts;
public final boolean mUseDoubleSpacePeriod;
public final boolean mBlockPotentiallyOffensive;
+ // Use bigrams to predict the next word when there is no input for it yet
+ public final boolean mBigramPredictionEnabled;
public final boolean mGestureInputEnabled;
public final boolean mGestureTrailEnabled;
public final boolean mGestureFloatingPreviewTextEnabled;
public final boolean mSlidingKeyInputPreviewEnabled;
public final int mKeyLongpressTimeout;
public final boolean mEnableEmojiAltPhysicalKey;
+ public final boolean mCloudSyncEnabled;
public final boolean mEnableMetricsLogging;
public final boolean mShouldShowLxxSuggestionUi;
// Use split layout for keyboard.
@@ -135,9 +138,6 @@ public class SettingsValues {
mShowsVoiceInputKey = needsToShowVoiceInputKey(prefs, res)
&& mInputAttributes.mShouldShowVoiceInputKey
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN;
- final String autoCorrectionThresholdRawValue = prefs.getString(
- Settings.PREF_AUTO_CORRECTION_THRESHOLD,
- res.getString(R.string.auto_correction_threshold_mode_index_modest));
mIncludesOtherImesInLanguageSwitchList = Settings.ENABLE_SHOW_LANGUAGE_SWITCH_KEY_SETTINGS
? prefs.getBoolean(Settings.PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST, false)
: true /* forcibly */;
@@ -148,7 +148,11 @@ public class SettingsValues {
mUseDoubleSpacePeriod = prefs.getBoolean(Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD, true)
&& inputAttributes.mIsGeneralTextInput;
mBlockPotentiallyOffensive = Settings.readBlockPotentiallyOffensive(prefs, res);
- mAutoCorrectEnabled = Settings.readAutoCorrectEnabled(autoCorrectionThresholdRawValue, res);
+ mAutoCorrectEnabled = Settings.readAutoCorrectEnabled(prefs, res);
+ final String autoCorrectionThresholdRawValue = mAutoCorrectEnabled
+ ? res.getString(R.string.auto_correction_threshold_mode_index_modest)
+ : res.getString(R.string.auto_correction_threshold_mode_index_off);
+ mBigramPredictionEnabled = readBigramPredictionEnabled(prefs, res);
mDoubleSpacePeriodTimeout = res.getInteger(R.integer.config_double_space_period_timeout);
mHasHardwareKeyboard = Settings.readHasHardwareKeyboard(res.getConfiguration());
mEnableMetricsLogging = prefs.getBoolean(Settings.PREF_ENABLE_METRICS_LOGGING, true);
@@ -169,6 +173,7 @@ public class SettingsValues {
mPlausibilityThreshold = Settings.readPlausibilityThreshold(res);
mGestureInputEnabled = Settings.readGestureInputEnabled(prefs, res);
mGestureTrailEnabled = prefs.getBoolean(Settings.PREF_GESTURE_PREVIEW_TRAIL, true);
+ mCloudSyncEnabled = prefs.getBoolean(LocalSettingsConstants.PREF_ENABLE_CLOUD_SYNC, false);
mAccount = prefs.getString(LocalSettingsConstants.PREF_ACCOUNT_NAME,
null /* default */);
mGestureFloatingPreviewTextEnabled = !mInputAttributes.mDisableGestureFloatingPreviewText
@@ -232,6 +237,10 @@ public class SettingsValues {
return mSuggestionsEnabledPerUserSettings;
}
+ public boolean isPersonalizationEnabled() {
+ return mUsePersonalizedDicts;
+ }
+
public boolean isWordSeparator(final int code) {
return mSpacingAndPunctuations.isWordSeparator(code);
}
@@ -302,6 +311,12 @@ public class SettingsValues {
return prefs.getBoolean(Settings.PREF_SHOW_SUGGESTIONS, true);
}
+ private static boolean readBigramPredictionEnabled(final SharedPreferences prefs,
+ final Resources res) {
+ return prefs.getBoolean(Settings.PREF_BIGRAM_PREDICTIONS, res.getBoolean(
+ R.bool.config_default_next_word_prediction));
+ }
+
private static float readAutoCorrectionThreshold(final Resources res,
final String currentAutoCorrectionSetting) {
final String[] autoCorrectionThresholdValues = res.getStringArray(
@@ -379,6 +394,8 @@ public class SettingsValues {
sb.append("" + mUseDoubleSpacePeriod);
sb.append("\n mBlockPotentiallyOffensive = ");
sb.append("" + mBlockPotentiallyOffensive);
+ sb.append("\n mBigramPredictionEnabled = ");
+ sb.append("" + mBigramPredictionEnabled);
sb.append("\n mGestureInputEnabled = ");
sb.append("" + mGestureInputEnabled);
sb.append("\n mGestureTrailEnabled = ");
diff --git a/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java b/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java
index c3b30dcb4..bee22afd5 100644
--- a/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java
+++ b/java/src/com/android/inputmethod/latin/setup/SetupWizardActivity.java
@@ -265,6 +265,8 @@ public final class SetupWizardActivity extends Activity implements View.OnClickL
intent.setClass(this, SettingsActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ intent.putExtra(SettingsActivity.EXTRA_ENTRY_KEY,
+ SettingsActivity.EXTRA_ENTRY_VALUE_APP_ICON);
startActivity(intent);
}
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/UserDictionaryLookup.java b/java/src/com/android/inputmethod/latin/spellcheck/UserDictionaryLookup.java
index 6ab741ca1..f2491f478 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/UserDictionaryLookup.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/UserDictionaryLookup.java
@@ -143,8 +143,8 @@ public class UserDictionaryLookup implements Closeable {
}
// Schedule a new reload after RELOAD_DELAY_MS.
- mReloadFuture = ExecutorUtils.getBackgroundExecutor().schedule(
- mLoader, RELOAD_DELAY_MS, TimeUnit.MILLISECONDS);
+ mReloadFuture = ExecutorUtils.getBackgroundExecutor(ExecutorUtils.SPELLING)
+ .schedule(mLoader, RELOAD_DELAY_MS, TimeUnit.MILLISECONDS);
}
}
private final ContentObserver mObserver = new UserDictionaryContentObserver();
@@ -186,7 +186,7 @@ public class UserDictionaryLookup implements Closeable {
// Schedule the initial load to run immediately. It's possible that the first call to
// isValidWord occurs before the dictionary has actually loaded, so it should not
// assume that the dictionary has been loaded.
- ExecutorUtils.getBackgroundExecutor().execute(mLoader);
+ ExecutorUtils.getBackgroundExecutor(ExecutorUtils.SPELLING).execute(mLoader);
// Register the observer to be notified on changes to the UserDictionary and all individual
// items.
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
index 17525f650..7dd0f03df 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
@@ -213,7 +213,8 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
// it has been shown once already or not, and if in the setup wizard). If applicable, it shows
// the notice. In all cases, it returns true if it was shown, false otherwise.
public boolean maybeShowImportantNoticeTitle() {
- if (!ImportantNoticeUtils.shouldShowImportantNotice(getContext())) {
+ final SettingsValues currentSettingsValues = Settings.getInstance().getCurrent();
+ if (!ImportantNoticeUtils.shouldShowImportantNotice(getContext(), currentSettingsValues)) {
return false;
}
if (getWidth() <= 0) {
diff --git a/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java b/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java
index a78446103..8ce6eff92 100644
--- a/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/ExecutorUtils.java
@@ -33,17 +33,30 @@ public class ExecutorUtils {
private static final String TAG = "ExecutorUtils";
- private static ScheduledExecutorService sExecutorService =
- Executors.newSingleThreadScheduledExecutor(new ExecutorFactory());
+ public static final String KEYBOARD = "Keyboard";
+ public static final String SPELLING = "Spelling";
+
+ private static ScheduledExecutorService sKeyboardExecutorService = newExecutorService(KEYBOARD);
+ private static ScheduledExecutorService sSpellingExecutorService = newExecutorService(SPELLING);
+
+ private static ScheduledExecutorService newExecutorService(final String name) {
+ return Executors.newSingleThreadScheduledExecutor(new ExecutorFactory(name));
+ }
private static class ExecutorFactory implements ThreadFactory {
+ private final String mName;
+
+ private ExecutorFactory(final String name) {
+ mName = name;
+ }
+
@Override
public Thread newThread(final Runnable runnable) {
Thread thread = new Thread(runnable, TAG);
thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable ex) {
- Log.w(TAG + "-" + runnable.getClass().getSimpleName(), ex);
+ Log.w(mName + "-" + runnable.getClass().getSimpleName(), ex);
}
});
return thread;
@@ -64,24 +77,44 @@ public class ExecutorUtils {
//
/**
+ * @param name Executor's name.
* @return scheduled executor service used to run background tasks
*/
- public static ScheduledExecutorService getBackgroundExecutor() {
+ public static ScheduledExecutorService getBackgroundExecutor(final String name) {
if (sExecutorServiceForTests != null) {
return sExecutorServiceForTests;
}
- return sExecutorService;
+ switch (name) {
+ case KEYBOARD:
+ return sKeyboardExecutorService;
+ case SPELLING:
+ return sSpellingExecutorService;
+ default:
+ throw new IllegalArgumentException("Invalid executor: " + name);
+ }
}
- public static void killTasks() {
- getBackgroundExecutor().shutdownNow();
+ public static void killTasks(final String name) {
+ final ScheduledExecutorService executorService = getBackgroundExecutor(name);
+ executorService.shutdownNow();
try {
- getBackgroundExecutor().awaitTermination(5, TimeUnit.SECONDS);
+ executorService.awaitTermination(5, TimeUnit.SECONDS);
} catch (InterruptedException e) {
- Log.wtf(TAG, "Failed to shut down background task.");
- throw new IllegalStateException("Failed to shut down background task.");
- } finally {
- sExecutorService = Executors.newSingleThreadScheduledExecutor(new ExecutorFactory());
+ Log.wtf(TAG, "Failed to shut down: " + name);
+ }
+ if (executorService == sExecutorServiceForTests) {
+ // Don't do anything to the test service.
+ return;
+ }
+ switch (name) {
+ case KEYBOARD:
+ sKeyboardExecutorService = newExecutorService(KEYBOARD);
+ break;
+ case SPELLING:
+ sSpellingExecutorService = newExecutorService(SPELLING);
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid executor: " + name);
}
}
diff --git a/java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java b/java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java
index 142548b25..df0cd8437 100644
--- a/java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/ImportantNoticeUtils.java
@@ -25,6 +25,7 @@ import android.util.Log;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.settings.SettingsValues;
import java.util.concurrent.TimeUnit;
@@ -105,7 +106,12 @@ public final class ImportantNoticeUtils {
return elapsedTime >= TIMEOUT_OF_IMPORTANT_NOTICE;
}
- public static boolean shouldShowImportantNotice(final Context context) {
+ public static boolean shouldShowImportantNotice(final Context context,
+ final SettingsValues settingsValues) {
+ // Check to see whether personalization is enabled by the user.
+ if (!settingsValues.isPersonalizationEnabled()) {
+ return false;
+ }
if (!hasNewImportantNotice(context)) {
return false;
}
diff --git a/java/src/com/android/inputmethod/latin/utils/ManagedProfileUtils.java b/java/src/com/android/inputmethod/latin/utils/ManagedProfileUtils.java
index f0d6d081e..1bd8f314c 100644
--- a/java/src/com/android/inputmethod/latin/utils/ManagedProfileUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/ManagedProfileUtils.java
@@ -23,6 +23,8 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.util.Log;
+import com.android.inputmethod.annotations.UsedForTesting;
+
import java.util.List;
/**
@@ -32,16 +34,28 @@ public class ManagedProfileUtils {
private static final boolean DEBUG = false;
private static final String TAG = ManagedProfileUtils.class.getSimpleName();
+ private static ManagedProfileUtils INSTANCE = new ManagedProfileUtils();
+ private static ManagedProfileUtils sTestInstance;
+
private ManagedProfileUtils() {
// This utility class is not publicly instantiable.
}
+ @UsedForTesting
+ public static void setTestInstance(final ManagedProfileUtils testInstance) {
+ sTestInstance = testInstance;
+ }
+
+ public static ManagedProfileUtils getInstance() {
+ return sTestInstance == null ? INSTANCE : sTestInstance;
+ }
+
/**
* Note that {@link UserManager#getUserProfiles} has been introduced
* in API level 21 (Build.VERSION_CODES.LOLLIPOP).
*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
- public static boolean hasManagedWorkProfile(final Context context) {
+ public boolean hasManagedWorkProfile(final Context context) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
return false;
}
diff --git a/java/src/com/android/inputmethod/latin/utils/NgramContextUtils.java b/java/src/com/android/inputmethod/latin/utils/NgramContextUtils.java
index 727df1a93..c05ffd693 100644
--- a/java/src/com/android/inputmethod/latin/utils/NgramContextUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/NgramContextUtils.java
@@ -31,6 +31,7 @@ public final class NgramContextUtils {
// Intentional empty constructor for utility class.
}
+ private static final Pattern NEWLINE_REGEX = Pattern.compile("[\\r\\n]+");
private static final Pattern SPACE_REGEX = Pattern.compile("\\s+");
// Get context information from nth word before the cursor. n = 1 retrieves the words
// immediately before the cursor, n = 2 retrieves the words before that, and so on. This splits
@@ -58,7 +59,11 @@ public final class NgramContextUtils {
public static NgramContext getNgramContextFromNthPreviousWord(final CharSequence prev,
final SpacingAndPunctuations spacingAndPunctuations, final int n) {
if (prev == null) return NgramContext.EMPTY_PREV_WORDS_INFO;
- final String[] w = SPACE_REGEX.split(prev);
+ final String[] lines = NEWLINE_REGEX.split(prev);
+ if (lines.length == 0) {
+ return new NgramContext(WordInfo.BEGINNING_OF_SENTENCE_WORD_INFO);
+ }
+ final String[] w = SPACE_REGEX.split(lines[lines.length - 1]);
final WordInfo[] prevWordsInfo =
new WordInfo[DecoderSpecificConstants.MAX_PREV_WORD_COUNT_FOR_N_GRAM];
Arrays.fill(prevWordsInfo, WordInfo.EMPTY_WORD_INFO);
@@ -81,16 +86,17 @@ public final class NgramContextUtils {
prevWordsInfo[i] = WordInfo.BEGINNING_OF_SENTENCE_WORD_INFO;
break;
}
+
final String focusedWord = w[focusedWordIndex];
- // If the word is, the context is beginning-of-sentence.
+ // If the word is empty, the context is beginning-of-sentence.
final int length = focusedWord.length();
if (length <= 0) {
prevWordsInfo[i] = WordInfo.BEGINNING_OF_SENTENCE_WORD_INFO;
break;
}
- // If ends in a sentence separator, the context is beginning-of-sentence.
+ // If the word ends in a sentence terminator, the context is beginning-of-sentence.
final char lastChar = focusedWord.charAt(length - 1);
- if (spacingAndPunctuations.isSentenceSeparator(lastChar)) {
+ if (spacingAndPunctuations.isSentenceTerminator(lastChar)) {
prevWordsInfo[i] = WordInfo.BEGINNING_OF_SENTENCE_WORD_INFO;
break;
}