aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/GestureFloatingPreviewText.java1
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java5
-rw-r--r--java/src/com/android/inputmethod/latin/SettingsFragment.java51
-rw-r--r--java/src/com/android/inputmethod/research/FixedLogBuffer.java5
-rw-r--r--java/src/com/android/inputmethod/research/LogUnit.java94
-rw-r--r--java/src/com/android/inputmethod/research/MainLogBuffer.java27
-rw-r--r--java/src/com/android/inputmethod/research/ResearchLogger.java19
7 files changed, 152 insertions, 50 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/internal/GestureFloatingPreviewText.java b/java/src/com/android/inputmethod/keyboard/internal/GestureFloatingPreviewText.java
index 0954a7a5d..28655a930 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/GestureFloatingPreviewText.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/GestureFloatingPreviewText.java
@@ -157,6 +157,7 @@ public class GestureFloatingPreviewText extends AbstractDrawingPreview {
*/
protected void updatePreviewPosition() {
if (mSuggestedWords.isEmpty() || TextUtils.isEmpty(mSuggestedWords.getWord(0))) {
+ getDrawingView().invalidate();
return;
}
final String text = mSuggestedWords.getWord(0);
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index fc9953ac0..70eb6e657 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1647,7 +1647,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
mExpectingUpdateSelection = true;
mConnection.endBatchEdit();
if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_onEndBatchInput(batchInputText, 0);
+ ResearchLogger.latinIME_onEndBatchInput(batchInputText, 0, suggestedWords);
}
// Space state must be updated before calling updateShiftState
mSpaceState = SPACE_STATE_PHANTOM;
@@ -2123,8 +2123,9 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
Stats.onAutoCorrection(typedWord, autoCorrection, separatorString, mWordComposer);
}
if (ProductionFlag.IS_EXPERIMENTAL) {
+ final SuggestedWords suggestedWords = mSuggestionStripView.getSuggestions();
ResearchLogger.latinIme_commitCurrentAutoCorrection(typedWord, autoCorrection,
- separatorString, mWordComposer.isBatchMode());
+ separatorString, mWordComposer.isBatchMode(), suggestedWords);
}
mExpectingUpdateSelection = true;
commitChosenWord(autoCorrection, LastComposedWord.COMMIT_TYPE_DECIDED_WORD,
diff --git a/java/src/com/android/inputmethod/latin/SettingsFragment.java b/java/src/com/android/inputmethod/latin/SettingsFragment.java
index 7f3d1ae6a..f0c51e194 100644
--- a/java/src/com/android/inputmethod/latin/SettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/SettingsFragment.java
@@ -41,7 +41,6 @@ public final class SettingsFragment extends InputMethodSettingsFragment
private ListPreference mKeyPreviewPopupDismissDelay;
// Use bigrams to predict the next word when there is no input for it yet
private CheckBoxPreference mBigramPrediction;
- private Preference mDebugSettingsPreference;
private void setPreferenceEnabled(final String preferenceKey, final boolean enabled) {
final Preference preference = findPreference(preferenceKey);
@@ -50,11 +49,14 @@ public final class SettingsFragment extends InputMethodSettingsFragment
}
}
- private void ensureConsistencyOfAutoCorrectionSettings() {
- final String autoCorrectionOff = getResources().getString(
- R.string.auto_correction_threshold_mode_index_off);
- final String currentSetting = mAutoCorrectionThresholdPreference.getValue();
- mBigramPrediction.setEnabled(!currentSetting.equals(autoCorrectionOff));
+ private static void removePreference(final String preferenceKey, final PreferenceGroup parent) {
+ if (parent == null) {
+ return;
+ }
+ final Preference preference = parent.findPreference(preferenceKey);
+ if (preference != null) {
+ parent.removePreference(preference);
+ }
}
@Override
@@ -84,22 +86,18 @@ public final class SettingsFragment extends InputMethodSettingsFragment
final PreferenceGroup generalSettings =
(PreferenceGroup) findPreference(Settings.PREF_GENERAL_SETTINGS);
- final PreferenceGroup textCorrectionGroup =
- (PreferenceGroup) findPreference(Settings.PREF_CORRECTION_SETTINGS);
- final PreferenceGroup gestureTypingSettings =
- (PreferenceGroup) findPreference(Settings.PREF_GESTURE_SETTINGS);
final PreferenceGroup miscSettings =
(PreferenceGroup) findPreference(Settings.PREF_MISC_SETTINGS);
- mDebugSettingsPreference = findPreference(Settings.PREF_DEBUG_SETTINGS);
- if (mDebugSettingsPreference != null) {
+ final Preference debugSettings = findPreference(Settings.PREF_DEBUG_SETTINGS);
+ if (debugSettings != null) {
if (ProductionFlag.IS_INTERNAL) {
final Intent debugSettingsIntent = new Intent(Intent.ACTION_MAIN);
debugSettingsIntent.setClassName(
context.getPackageName(), DebugSettingsActivity.class.getName());
- mDebugSettingsPreference.setIntent(debugSettingsIntent);
+ debugSettings.setIntent(debugSettingsIntent);
} else {
- miscSettings.removePreference(mDebugSettingsPreference);
+ miscSettings.removePreference(debugSettings);
}
}
@@ -112,11 +110,8 @@ public final class SettingsFragment extends InputMethodSettingsFragment
final PreferenceGroup advancedSettings =
(PreferenceGroup) findPreference(Settings.PREF_ADVANCED_SETTINGS);
if (!AudioAndHapticFeedbackManager.getInstance().hasVibrator()) {
- generalSettings.removePreference(findPreference(Settings.PREF_VIBRATE_ON));
- if (null != advancedSettings) { // Theoretically advancedSettings cannot be null
- advancedSettings.removePreference(
- findPreference(Settings.PREF_VIBRATION_DURATION_SETTINGS));
- }
+ removePreference(Settings.PREF_VIBRATE_ON, generalSettings);
+ removePreference(Settings.PREF_VIBRATION_DURATION_SETTINGS, advancedSettings);
}
final boolean showKeyPreviewPopupOption = res.getBoolean(
@@ -124,10 +119,8 @@ public final class SettingsFragment extends InputMethodSettingsFragment
mKeyPreviewPopupDismissDelay =
(ListPreference) findPreference(Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY);
if (!showKeyPreviewPopupOption) {
- generalSettings.removePreference(findPreference(Settings.PREF_POPUP_ON));
- if (null != advancedSettings) { // Theoretically advancedSettings cannot be null
- advancedSettings.removePreference(mKeyPreviewPopupDismissDelay);
- }
+ removePreference(Settings.PREF_POPUP_ON, generalSettings);
+ removePreference(Settings.PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY, advancedSettings);
} else {
final String[] entries = new String[] {
res.getString(R.string.key_preview_popup_dismiss_no_delay),
@@ -148,10 +141,11 @@ public final class SettingsFragment extends InputMethodSettingsFragment
setPreferenceEnabled(Settings.PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST,
Settings.readShowsLanguageSwitchKey(prefs));
+ final PreferenceGroup textCorrectionGroup =
+ (PreferenceGroup) findPreference(Settings.PREF_CORRECTION_SETTINGS);
final PreferenceScreen dictionaryLink =
(PreferenceScreen) findPreference(Settings.PREF_CONFIGURE_DICTIONARIES_KEY);
final Intent intent = dictionaryLink.getIntent();
-
final int number = context.getPackageManager().queryIntentActivities(intent, 0).size();
// TODO: The experimental version is not supported by the Dictionary Pack Service yet
if (ProductionFlag.IS_EXPERIMENTAL || 0 >= number) {
@@ -161,7 +155,7 @@ public final class SettingsFragment extends InputMethodSettingsFragment
final boolean gestureInputEnabledByBuildConfig = res.getBoolean(
R.bool.config_gesture_input_enabled_by_build_config);
if (!gestureInputEnabledByBuildConfig) {
- getPreferenceScreen().removePreference(gestureTypingSettings);
+ removePreference(Settings.PREF_GESTURE_SETTINGS, getPreferenceScreen());
}
setupKeyLongpressTimeoutSettings(prefs, res);
@@ -219,6 +213,13 @@ public final class SettingsFragment extends InputMethodSettingsFragment
refreshEnablingsOfKeypressSoundAndVibrationSettings(prefs, getResources());
}
+ private void ensureConsistencyOfAutoCorrectionSettings() {
+ final String autoCorrectionOff = getResources().getString(
+ R.string.auto_correction_threshold_mode_index_off);
+ final String currentSetting = mAutoCorrectionThresholdPreference.getValue();
+ mBigramPrediction.setEnabled(!currentSetting.equals(autoCorrectionOff));
+ }
+
private void updateShowCorrectionSuggestionsSummary() {
mShowCorrectionSuggestionsPreference.setSummary(
getResources().getStringArray(R.array.prefs_suggestion_visibilities)
diff --git a/java/src/com/android/inputmethod/research/FixedLogBuffer.java b/java/src/com/android/inputmethod/research/FixedLogBuffer.java
index 73f284a73..78dc59562 100644
--- a/java/src/com/android/inputmethod/research/FixedLogBuffer.java
+++ b/java/src/com/android/inputmethod/research/FixedLogBuffer.java
@@ -61,7 +61,7 @@ public class FixedLogBuffer extends LogBuffer {
*/
@Override
public void shiftIn(final LogUnit newLogUnit) {
- if (newLogUnit.getWord() == null) {
+ if (!newLogUnit.hasWord()) {
// This LogUnit isn't a word, so it doesn't count toward the word-limit.
super.shiftIn(newLogUnit);
return;
@@ -153,8 +153,7 @@ public class FixedLogBuffer extends LogBuffer {
for (int i = 0; i < length && n > 0; i++) {
final LogUnit logUnit = logUnits.get(i);
list.add(logUnit);
- final String word = logUnit.getWord();
- if (word != null) {
+ if (logUnit.hasWord()) {
n--;
}
}
diff --git a/java/src/com/android/inputmethod/research/LogUnit.java b/java/src/com/android/inputmethod/research/LogUnit.java
index 715000d28..638b7d9d4 100644
--- a/java/src/com/android/inputmethod/research/LogUnit.java
+++ b/java/src/com/android/inputmethod/research/LogUnit.java
@@ -17,6 +17,7 @@
package com.android.inputmethod.research;
import android.content.SharedPreferences;
+import android.text.TextUtils;
import android.util.JsonWriter;
import android.util.Log;
import android.view.MotionEvent;
@@ -57,16 +58,32 @@ import java.util.Map;
// Assume that mTimeList is sorted in increasing order. Do not insert null values into
// mTimeList.
private final ArrayList<Long> mTimeList;
+ // Word that this LogUnit generates. Should be null if the LogUnit does not generate a genuine
+ // word (i.e. separators alone do not count as a word). Should never be empty.
private String mWord;
private boolean mMayContainDigit;
private boolean mIsPartOfMegaword;
private boolean mContainsCorrection;
+ // mCorrectionType indicates whether the word was corrected at all, and if so, whether it was
+ // to a different word or just a "typo" correction. It is considered a "typo" if the final
+ // word was listed in the suggestions available the first time the word was gestured or
+ // tapped.
+ private int mCorrectionType;
+ public static final int CORRECTIONTYPE_NO_CORRECTION = 0;
+ public static final int CORRECTIONTYPE_CORRECTION = 1;
+ public static final int CORRECTIONTYPE_DIFFERENT_WORD = 2;
+ public static final int CORRECTIONTYPE_TYPO = 3;
+
+ private SuggestedWords mSuggestedWords;
+
public LogUnit() {
mLogStatementList = new ArrayList<LogStatement>();
mValuesList = new ArrayList<Object[]>();
mTimeList = new ArrayList<Long>();
mIsPartOfMegaword = false;
+ mCorrectionType = CORRECTIONTYPE_NO_CORRECTION;
+ mSuggestedWords = null;
}
private LogUnit(final ArrayList<LogStatement> logStatementList,
@@ -77,6 +94,8 @@ import java.util.Map;
mValuesList = valuesList;
mTimeList = timeList;
mIsPartOfMegaword = isPartOfMegaword;
+ mCorrectionType = CORRECTIONTYPE_NO_CORRECTION;
+ mSuggestedWords = null;
}
private static final Object[] NULL_VALUES = new Object[0];
@@ -167,6 +186,7 @@ import java.util.Map;
private static final String UPTIME_KEY = "_ut";
private static final String EVENT_TYPE_KEY = "_ty";
private static final String WORD_KEY = "_wo";
+ private static final String CORRECTION_TYPE_KEY = "_corType";
private static final String LOG_UNIT_BEGIN_KEY = "logUnitStart";
private static final String LOG_UNIT_END_KEY = "logUnitEnd";
@@ -177,6 +197,7 @@ import java.util.Map;
jsonWriter.name(CURRENT_TIME_KEY).value(System.currentTimeMillis());
if (canIncludePrivateData) {
jsonWriter.name(WORD_KEY).value(getWord());
+ jsonWriter.name(CORRECTION_TYPE_KEY).value(getCorrectionType());
}
jsonWriter.name(EVENT_TYPE_KEY).value(LOG_UNIT_BEGIN_KEY);
jsonWriter.endObject();
@@ -254,7 +275,33 @@ import java.util.Map;
return true;
}
- public void setWord(String word) {
+ /**
+ * Mark the current logUnit as containing data to generate {@code word}.
+ *
+ * If {@code setWord()} was previously called for this LogUnit, then the method will try to
+ * determine what kind of correction it is, and update its internal state of the correctionType
+ * accordingly.
+ *
+ * @param word The word this LogUnit generates. Caller should not pass null or the empty
+ * string.
+ */
+ public void setWord(final String word) {
+ if (hasWord()) {
+ // The word was already set once, and it is now being changed. See if the new word
+ // is close to the old word. If so, then the change is probably a typo correction.
+ // If not, the user may have decided to enter a different word, so flag it.
+ if (mSuggestedWords != null) {
+ if (isInSuggestedWords(word, mSuggestedWords)) {
+ mCorrectionType = CORRECTIONTYPE_TYPO;
+ } else {
+ mCorrectionType = CORRECTIONTYPE_DIFFERENT_WORD;
+ }
+ } else {
+ // No suggested words, so it's not clear whether it's a typo or different word.
+ // Mark it as a generic correction.
+ mCorrectionType = CORRECTIONTYPE_CORRECTION;
+ }
+ }
mWord = word;
}
@@ -263,7 +310,7 @@ import java.util.Map;
}
public boolean hasWord() {
- return mWord != null;
+ return mWord != null && !TextUtils.isEmpty(mWord.trim());
}
public void setMayContainDigit() {
@@ -282,6 +329,14 @@ import java.util.Map;
return mContainsCorrection;
}
+ public void setCorrectionType(final int correctionType) {
+ mCorrectionType = correctionType;
+ }
+
+ public int getCorrectionType() {
+ return mCorrectionType;
+ }
+
public boolean isEmpty() {
return mLogStatementList.isEmpty();
}
@@ -328,8 +383,43 @@ import java.util.Map;
mValuesList.addAll(logUnit.mValuesList);
mTimeList.addAll(logUnit.mTimeList);
mWord = null;
+ if (logUnit.mWord != null) {
+ setWord(logUnit.mWord);
+ }
mMayContainDigit = mMayContainDigit || logUnit.mMayContainDigit;
mContainsCorrection = mContainsCorrection || logUnit.mContainsCorrection;
mIsPartOfMegaword = false;
}
+
+ public SuggestedWords getSuggestions() {
+ return mSuggestedWords;
+ }
+
+ /**
+ * Initialize the suggestions.
+ *
+ * Once set to a non-null value, the suggestions may not be changed again. This is to keep
+ * track of the list of words that are close to the user's initial effort to type the word.
+ * Only words that are close to the initial effort are considered typo corrections.
+ */
+ public void initializeSuggestions(final SuggestedWords suggestedWords) {
+ if (mSuggestedWords == null) {
+ mSuggestedWords = suggestedWords;
+ }
+ }
+
+ private static boolean isInSuggestedWords(final String queryWord,
+ final SuggestedWords suggestedWords) {
+ if (TextUtils.isEmpty(queryWord)) {
+ return false;
+ }
+ final int size = suggestedWords.size();
+ for (int i = 0; i < size; i++) {
+ final SuggestedWordInfo wordInfo = suggestedWords.getInfo(i);
+ if (queryWord.equals(wordInfo.mWord)) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/java/src/com/android/inputmethod/research/MainLogBuffer.java b/java/src/com/android/inputmethod/research/MainLogBuffer.java
index 57d5c41d7..3a87bf1df 100644
--- a/java/src/com/android/inputmethod/research/MainLogBuffer.java
+++ b/java/src/com/android/inputmethod/research/MainLogBuffer.java
@@ -117,20 +117,19 @@ public abstract class MainLogBuffer extends FixedLogBuffer {
if (IS_LOGGING_EVERYTHING) {
if (mIsStopping) {
return true;
- } else {
- // Only check that it is the right length. If not, wait for later words to make
- // complete n-grams.
- int numWordsInLogUnitList = 0;
- final int length = logUnits.size();
- for (int i = 0; i < length; i++) {
- final LogUnit logUnit = logUnits.get(i);
- final String word = logUnit.getWord();
- if (word != null) {
- numWordsInLogUnitList++;
- }
+ }
+ // Only check that it is the right length. If not, wait for later words to make
+ // complete n-grams.
+ int numWordsInLogUnitList = 0;
+ final int length = logUnits.size();
+ for (int i = 0; i < length; i++) {
+ final LogUnit logUnit = logUnits.get(i);
+ final String word = logUnit.getWord();
+ if (word != null) {
+ numWordsInLogUnitList++;
}
- return numWordsInLogUnitList >= minNGramSize;
}
+ return numWordsInLogUnitList >= minNGramSize;
}
// Check that we are not sampling too frequently. Having sampled recently might disclose
@@ -157,14 +156,14 @@ public abstract class MainLogBuffer extends FixedLogBuffer {
final int length = logUnits.size();
for (int i = 0; i < length; i++) {
final LogUnit logUnit = logUnits.get(i);
- final String word = logUnit.getWord();
- if (word == null) {
+ if (!logUnit.hasWord()) {
// Digits outside words are a privacy threat.
if (logUnit.mayContainDigit()) {
return false;
}
} else {
numWordsInLogUnitList++;
+ final String word = logUnit.getWord();
// Words not in the dictionary are a privacy threat.
if (ResearchLogger.hasLetters(word) && !(dictionary.isValidWord(word))) {
if (DEBUG) {
diff --git a/java/src/com/android/inputmethod/research/ResearchLogger.java b/java/src/com/android/inputmethod/research/ResearchLogger.java
index 2da571d5a..dbf2d2982 100644
--- a/java/src/com/android/inputmethod/research/ResearchLogger.java
+++ b/java/src/com/android/inputmethod/research/ResearchLogger.java
@@ -785,6 +785,10 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
mCurrentLogUnit.setContainsCorrection();
}
+ private void setCurrentLogUnitCorrectionType(final int correctionType) {
+ mCurrentLogUnit.setCorrectionType(correctionType);
+ }
+
/* package for test */ void commitCurrentLogUnit() {
if (DEBUG) {
Log.d(TAG, "commitCurrentLogUnit" + (mCurrentLogUnit.hasWord() ?
@@ -1234,13 +1238,17 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
"suggestion", "x", "y");
public static void latinIME_pickSuggestionManually(final String replacedWord,
final int index, final String suggestion, final boolean isBatchMode) {
- final String scrubbedWord = scrubDigitsFromString(suggestion);
final ResearchLogger researchLogger = getInstance();
+ if (!replacedWord.equals(suggestion.toString())) {
+ // The user choose something other than what was already there.
+ researchLogger.setCurrentLogUnitContainsCorrection();
+ researchLogger.setCurrentLogUnitCorrectionType(LogUnit.CORRECTIONTYPE_TYPO);
+ }
+ final String scrubbedWord = scrubDigitsFromString(suggestion);
researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_PICKSUGGESTIONMANUALLY,
scrubDigitsFromString(replacedWord), index,
suggestion == null ? null : scrubbedWord, Constants.SUGGESTION_STRIP_COORDINATE,
Constants.SUGGESTION_STRIP_COORDINATE);
- researchLogger.setCurrentLogUnitContainsCorrection();
researchLogger.commitCurrentLogUnitAsWord(scrubbedWord, Long.MAX_VALUE, isBatchMode);
researchLogger.mStatistics.recordManualSuggestion(SystemClock.uptimeMillis());
}
@@ -1530,10 +1538,12 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
new LogStatement("LatinIMECommitCurrentAutoCorrection", true, true, "typedWord",
"autoCorrection", "separatorString");
public static void latinIme_commitCurrentAutoCorrection(final String typedWord,
- final String autoCorrection, final String separatorString, final boolean isBatchMode) {
+ final String autoCorrection, final String separatorString, final boolean isBatchMode,
+ final SuggestedWords suggestedWords) {
final String scrubbedTypedWord = scrubDigitsFromString(typedWord);
final String scrubbedAutoCorrection = scrubDigitsFromString(autoCorrection);
final ResearchLogger researchLogger = getInstance();
+ researchLogger.mCurrentLogUnit.initializeSuggestions(suggestedWords);
researchLogger.commitCurrentLogUnitAsWord(scrubbedAutoCorrection, Long.MAX_VALUE,
isBatchMode);
@@ -1731,10 +1741,11 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
new LogStatement("LatinIMEOnEndBatchInput", true, false, "enteredText",
"enteredWordPos");
public static void latinIME_onEndBatchInput(final CharSequence enteredText,
- final int enteredWordPos) {
+ final int enteredWordPos, final SuggestedWords suggestedWords) {
final ResearchLogger researchLogger = getInstance();
researchLogger.enqueueEvent(LOGSTATEMENT_LATINIME_ONENDBATCHINPUT, enteredText,
enteredWordPos);
+ researchLogger.mCurrentLogUnit.initializeSuggestions(suggestedWords);
researchLogger.mStatistics.recordGestureInput(enteredText.length(),
SystemClock.uptimeMillis());
}