aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java8
-rw-r--r--java/src/com/android/inputmethod/latin/ResearchLogger.java73
-rw-r--r--java/src/com/android/inputmethod/latin/Settings.java24
-rw-r--r--java/src/com/android/inputmethod/latin/UserBinaryDictionary.java33
4 files changed, 74 insertions, 64 deletions
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index b8aab4cdf..8a5fc495e 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1002,8 +1002,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
// This will reset the whole input state to the starting state. It will clear
- // the composing word, reset the last composed word, tell the inputconnection
- // and the composingStateManager about it.
+ // the composing word, reset the last composed word, tell the inputconnection about it.
private void resetEntireInputState() {
resetComposingState(true /* alsoResetLastComposedWord */);
updateSuggestions();
@@ -1958,7 +1957,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// expect to receive non-words.
if (!mCurrentSettings.mCorrectionEnabled) return null;
- if (mUserHistoryDictionary != null) {
+ final UserHistoryDictionary userHistoryDictionary = mUserHistoryDictionary;
+ if (userHistoryDictionary != null) {
final CharSequence prevWord
= mConnection.getPreviousWord(mCurrentSettings.mWordSeparators);
final String secondWord;
@@ -1973,7 +1973,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final int maxFreq = AutoCorrection.getMaxFrequency(
mSuggest.getUnigramDictionaries(), suggestion);
if (maxFreq == 0) return null;
- mUserHistoryDictionary.addToUserHistory(null == prevWord ? null : prevWord.toString(),
+ userHistoryDictionary.addToUserHistory(null == prevWord ? null : prevWord.toString(),
secondWord, maxFreq > 0);
return prevWord;
}
diff --git a/java/src/com/android/inputmethod/latin/ResearchLogger.java b/java/src/com/android/inputmethod/latin/ResearchLogger.java
index ee596924f..cf3cc7873 100644
--- a/java/src/com/android/inputmethod/latin/ResearchLogger.java
+++ b/java/src/com/android/inputmethod/latin/ResearchLogger.java
@@ -379,29 +379,43 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
mCurrentLogUnit.addLogAtom(keys, values, false);
}
- private boolean isInDictionary(CharSequence word) {
- return (mDictionary != null) && (mDictionary.isValidWord(word));
+ /* package for test */ boolean isPrivacyThreat(String word) {
+ // currently: word not in dictionary or contains numbers.
+ if (TextUtils.isEmpty(word)) {
+ return false;
+ }
+ final int length = word.length();
+ boolean hasLetter = false;
+ for (int i = 0; i < length; i = word.offsetByCodePoints(i, 1)) {
+ final int codePoint = Character.codePointAt(word, i);
+ if (Character.isDigit(codePoint)) {
+ return true;
+ }
+ if (Character.isLetter(codePoint)) {
+ hasLetter = true;
+ break; // Word may contain digits, but will only be allowed if in the dictionary.
+ }
+ }
+ if (hasLetter) {
+ if (mDictionary == null && mSuggest != null && mSuggest.hasMainDictionary()) {
+ mDictionary = mSuggest.getMainDictionary();
+ }
+ if (mDictionary == null) {
+ // Can't access dictionary. Assume privacy threat.
+ return true;
+ }
+ return !(mDictionary.isValidWord(word));
+ }
+ // No letters, no numbers. Punctuation, space, or something else.
+ return false;
}
/**
- * Write out enqueued LogEvents to the log, filtered for privacy.
- *
- * If word is in the dictionary, then it is not privacy-sensitive and all LogEvents related to
- * it can be written to the log. If the word is not in the dictionary, then it may correspond
- * to a proper name, which might reveal private information, so neither the word nor any
- * information related to the word (e.g. the down/motion/up coordinates) should be revealed.
- * These LogEvents have been marked as privacy-sensitive; non privacy-sensitive events are still
- * written out.
- *
- * @param word the word to be checked for inclusion in the dictionary
+ * Write out enqueued LogEvents to the log, possibly dropping privacy sensitive events.
*/
- /* package for test */ synchronized void flushQueue(CharSequence word) {
+ /* package for test */ synchronized void flushQueue(boolean removePotentiallyPrivateEvents) {
if (isAllowedToLog()) {
- // check for dictionary
- if (mDictionary == null && mSuggest != null && mSuggest.hasMainDictionary()) {
- mDictionary = mSuggest.getMainDictionary();
- }
- mCurrentLogUnit.setIsPrivacySafe(word != null && isInDictionary(word));
+ mCurrentLogUnit.setRemovePotentiallyPrivateEvents(removePotentiallyPrivateEvents);
mLoggingHandler.post(mCurrentLogUnit);
mCurrentLogUnit = new LogUnit();
}
@@ -513,7 +527,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
private final List<String[]> mKeysList = new ArrayList<String[]>();
private final List<Object[]> mValuesList = new ArrayList<Object[]>();
private final List<Boolean> mIsPotentiallyPrivate = new ArrayList<Boolean>();
- private boolean mIsPrivacySafe = false;
+ private boolean mRemovePotentiallyPrivateEvents = true;
private void addLogAtom(final String[] keys, final Object[] values,
final Boolean isPotentiallyPrivate) {
@@ -522,15 +536,15 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
mIsPotentiallyPrivate.add(isPotentiallyPrivate);
}
- void setIsPrivacySafe(boolean isPrivacySafe) {
- mIsPrivacySafe = isPrivacySafe;
+ void setRemovePotentiallyPrivateEvents(boolean removePotentiallyPrivateEvents) {
+ mRemovePotentiallyPrivateEvents = removePotentiallyPrivateEvents;
}
@Override
public void run() {
final int numAtoms = mKeysList.size();
for (int atomIndex = 0; atomIndex < numAtoms; atomIndex++) {
- if (!mIsPrivacySafe && mIsPotentiallyPrivate.get(atomIndex)) {
+ if (mRemovePotentiallyPrivateEvents && mIsPotentiallyPrivate.get(atomIndex)) {
continue;
}
final String[] keys = mKeysList.get(atomIndex);
@@ -548,7 +562,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
StringBuilder sb = null;
final int length = s.length();
for (int i = 0; i < length; i = s.offsetByCodePoints(i, 1)) {
- int codePoint = Character.codePointAt(s, i);
+ final int codePoint = Character.codePointAt(s, i);
if (Character.isDigit(codePoint)) {
if (sb == null) {
sb = new StringBuilder(length);
@@ -638,19 +652,20 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
final ResearchLogger researchLogger = getInstance();
researchLogger.enqueuePotentiallyPrivateEvent(
EVENTKEYS_LATINIME_COMMITCURRENTAUTOCORRECTION, values);
- researchLogger.flushQueue(autoCorrection);
+ researchLogger.flushQueue(researchLogger.isPrivacyThreat(autoCorrection));
}
private static final String[] EVENTKEYS_LATINIME_COMMITTEXT = {
"LatinIMECommitText", "typedWord"
};
public static void latinIME_commitText(final CharSequence typedWord) {
+ final String scrubbedWord = scrubDigitsFromString(typedWord.toString());
final Object[] values = {
- scrubDigitsFromString(typedWord.toString())
+ scrubbedWord
};
final ResearchLogger researchLogger = getInstance();
researchLogger.enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_COMMITTEXT, values);
- researchLogger.flushQueue(typedWord);
+ researchLogger.flushQueue(researchLogger.isPrivacyThreat(scrubbedWord));
}
private static final String[] EVENTKEYS_LATINIME_DELETESURROUNDINGTEXT = {
@@ -728,7 +743,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
}
final ResearchLogger researchLogger = getInstance();
researchLogger.enqueueEvent(EVENTKEYS_LATINIME_ONWINDOWHIDDEN, values);
- researchLogger.flushQueue(null);
+ researchLogger.flushQueue(true); // Play it safe. Remove privacy-sensitive events.
}
}
@@ -809,7 +824,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
final ResearchLogger researchLogger = getInstance();
researchLogger.enqueuePotentiallyPrivateEvent(
EVENTKEYS_LATINIME_PICKAPPLICATIONSPECIFIEDCOMPLETION, values);
- researchLogger.flushQueue(cs.toString());
+ researchLogger.flushQueue(researchLogger.isPrivacyThreat(cs.toString()));
}
private static final String[] EVENTKEYS_LATINIME_PICKSUGGESTIONMANUALLY = {
@@ -824,7 +839,7 @@ public class ResearchLogger implements SharedPreferences.OnSharedPreferenceChang
final ResearchLogger researchLogger = getInstance();
researchLogger.enqueuePotentiallyPrivateEvent(EVENTKEYS_LATINIME_PICKSUGGESTIONMANUALLY,
values);
- researchLogger.flushQueue(suggestion.toString());
+ researchLogger.flushQueue(researchLogger.isPrivacyThreat(suggestion.toString()));
}
private static final String[] EVENTKEYS_LATINIME_PUNCTUATIONSUGGESTION = {
diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java
index 152d66851..4c67b4957 100644
--- a/java/src/com/android/inputmethod/latin/Settings.java
+++ b/java/src/com/android/inputmethod/latin/Settings.java
@@ -69,9 +69,7 @@ public class Settings extends InputMethodSettingsFragment
public static final String PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY =
"pref_key_preview_popup_dismiss_delay";
public static final String PREF_KEY_USE_CONTACTS_DICT = "pref_key_use_contacts_dict";
- public static final String PREF_BIGRAM_SUGGESTION = "next_word_suggestion";
public static final String PREF_BIGRAM_PREDICTIONS = "next_word_prediction";
- public static final String PREF_KEY_ENABLE_SPAN_INSERT = "enable_span_insert";
public static final String PREF_VIBRATION_DURATION_SETTINGS =
"pref_vibration_duration_settings";
public static final String PREF_KEYPRESS_SOUND_VOLUME =
@@ -87,9 +85,7 @@ public class Settings extends InputMethodSettingsFragment
private ListPreference mShowCorrectionSuggestionsPreference;
private ListPreference mAutoCorrectionThresholdPreference;
private ListPreference mKeyPreviewPopupDismissDelay;
- // Suggestion: use bigrams to adjust scores of suggestions obtained from unigram dictionary
- private CheckBoxPreference mBigramSuggestion;
- // Prediction: use bigrams to predict the next word when there is no input for it yet
+ // Use bigrams to predict the next word when there is no input for it yet
private CheckBoxPreference mBigramPrediction;
private Preference mDebugSettingsPreference;
@@ -100,7 +96,6 @@ public class Settings extends InputMethodSettingsFragment
final String autoCorrectionOff = getResources().getString(
R.string.auto_correction_threshold_mode_index_off);
final String currentSetting = mAutoCorrectionThresholdPreference.getValue();
- mBigramSuggestion.setEnabled(!currentSetting.equals(autoCorrectionOff));
if (null != mBigramPrediction) {
mBigramPrediction.setEnabled(!currentSetting.equals(autoCorrectionOff));
}
@@ -124,7 +119,6 @@ public class Settings extends InputMethodSettingsFragment
mAutoCorrectionThresholdPreference =
(ListPreference) findPreference(PREF_AUTO_CORRECTION_THRESHOLD);
- mBigramSuggestion = (CheckBoxPreference) findPreference(PREF_BIGRAM_SUGGESTION);
mBigramPrediction = (CheckBoxPreference) findPreference(PREF_BIGRAM_PREDICTIONS);
mDebugSettingsPreference = findPreference(PREF_DEBUG_SETTINGS);
if (mDebugSettingsPreference != null) {
@@ -149,12 +143,9 @@ public class Settings extends InputMethodSettingsFragment
generalSettings.removePreference(mVoicePreference);
}
- final PreferenceGroup advancedSettings =
- (PreferenceGroup) findPreference(PREF_ADVANCED_SETTINGS);
- // Remove those meaningless options for now. TODO: delete them for good
- advancedSettings.removePreference(findPreference(PREF_BIGRAM_SUGGESTION));
- advancedSettings.removePreference(findPreference(PREF_KEY_ENABLE_SPAN_INSERT));
if (!VibratorUtils.getInstance(context).hasVibrator()) {
+ final PreferenceGroup advancedSettings =
+ (PreferenceGroup) findPreference(PREF_ADVANCED_SETTINGS);
generalSettings.removePreference(findPreference(PREF_VIBRATE_ON));
if (null != advancedSettings) { // Theoretically advancedSettings cannot be null
advancedSettings.removePreference(findPreference(PREF_VIBRATION_DURATION_SETTINGS));
@@ -167,15 +158,6 @@ public class Settings extends InputMethodSettingsFragment
generalSettings.removePreference(findPreference(PREF_POPUP_ON));
}
- final boolean showBigramSuggestionsOption = res.getBoolean(
- R.bool.config_enable_next_word_suggestions_option);
- if (!showBigramSuggestionsOption) {
- textCorrectionGroup.removePreference(mBigramSuggestion);
- if (null != mBigramPrediction) {
- textCorrectionGroup.removePreference(mBigramPrediction);
- }
- }
-
final CheckBoxPreference includeOtherImesInLanguageSwitchList =
(CheckBoxPreference)findPreference(PREF_INCLUDE_OTHER_IMES_IN_LANGUAGE_SWITCH_LIST);
includeOtherImesInLanguageSwitchList.setEnabled(
diff --git a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
index 6fa1a25a1..5bcdb57b5 100644
--- a/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserBinaryDictionary.java
@@ -36,11 +36,22 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
// TODO: use Words.SHORTCUT when it's public in the SDK
final static String SHORTCUT = "shortcut";
- private static final String[] PROJECTION_QUERY = {
- Words.WORD,
- SHORTCUT,
- Words.FREQUENCY,
- };
+ private static final String[] PROJECTION_QUERY;
+ static {
+ // 16 is JellyBean, but we want this to compile against ICS.
+ if (android.os.Build.VERSION.SDK_INT >= 16) {
+ PROJECTION_QUERY = new String[] {
+ Words.WORD,
+ SHORTCUT,
+ Words.FREQUENCY,
+ };
+ } else {
+ PROJECTION_QUERY = new String[] {
+ Words.WORD,
+ Words.FREQUENCY,
+ };
+ }
+ }
private static final String NAME = "userunigram";
@@ -136,7 +147,7 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
requestArguments = localeElements;
}
final Cursor cursor = mContext.getContentResolver().query(
- Words.CONTENT_URI, PROJECTION_QUERY, request.toString(), requestArguments, null);
+ Words.CONTENT_URI, PROJECTION_QUERY, request.toString(), requestArguments, null);
try {
addWords(cursor);
} finally {
@@ -182,16 +193,18 @@ public class UserBinaryDictionary extends ExpandableBinaryDictionary {
}
private void addWords(Cursor cursor) {
+ // 16 is JellyBean, but we want this to compile against ICS.
+ final boolean hasShortcutColumn = android.os.Build.VERSION.SDK_INT >= 16;
clearFusionDictionary();
if (cursor == null) return;
if (cursor.moveToFirst()) {
final int indexWord = cursor.getColumnIndex(Words.WORD);
- final int indexShortcut = cursor.getColumnIndex(SHORTCUT);
+ final int indexShortcut = hasShortcutColumn ? cursor.getColumnIndex(SHORTCUT) : 0;
final int indexFrequency = cursor.getColumnIndex(Words.FREQUENCY);
while (!cursor.isAfterLast()) {
- String word = cursor.getString(indexWord);
- String shortcut = cursor.getString(indexShortcut);
- int frequency = cursor.getInt(indexFrequency);
+ final String word = cursor.getString(indexWord);
+ final String shortcut = hasShortcutColumn ? cursor.getString(indexShortcut) : null;
+ final int frequency = cursor.getInt(indexFrequency);
// Safeguard against adding really long words.
if (word.length() < MAX_WORD_LENGTH) {
super.addWord(word, null, frequency);