aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryFacilitator.java6
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java10
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryFactory.java2
-rw-r--r--java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java2
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java8
-rw-r--r--java/src/com/android/inputmethod/latin/Suggest.java51
-rw-r--r--java/src/com/android/inputmethod/latin/SuggestedWords.java33
-rw-r--r--java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java12
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java85
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/DictionaryDecayBroadcastReciever.java89
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java53
-rw-r--r--java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java41
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java10
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java29
-rw-r--r--java/src/com/android/inputmethod/latin/utils/BinaryDictionaryUtils.java5
-rw-r--r--java/src/com/android/inputmethod/latin/utils/SuggestionResults.java15
16 files changed, 130 insertions, 321 deletions
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
index 6b939cdfe..9ea1950f5 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitator.java
@@ -20,7 +20,7 @@ import android.content.Context;
import android.util.Pair;
import com.android.inputmethod.annotations.UsedForTesting;
-import com.android.inputmethod.keyboard.KeyboardLayout;
+import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.latin.common.ComposedData;
import com.android.inputmethod.latin.settings.SettingsValuesForSuggestion;
import com.android.inputmethod.latin.utils.SuggestionResults;
@@ -157,9 +157,9 @@ public interface DictionaryFacilitator {
// TODO: Revise the way to fusion suggestion results.
SuggestionResults getSuggestionResults(final ComposedData composedData,
- final NgramContext ngramContext, final long proximityInfoHandle,
+ final NgramContext ngramContext, @Nonnull final Keyboard keyboard,
final SettingsValuesForSuggestion settingsValuesForSuggestion, final int sessionId,
- final int inputStyle, final KeyboardLayout keyboardLayout);
+ final int inputStyle);
boolean isValidSpellingWord(final String word);
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java
index e96300020..763cfa26d 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorImpl.java
@@ -22,7 +22,7 @@ import android.util.Log;
import android.util.Pair;
import com.android.inputmethod.annotations.UsedForTesting;
-import com.android.inputmethod.keyboard.KeyboardLayout;
+import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.latin.NgramContext.WordInfo;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.common.ComposedData;
@@ -668,12 +668,14 @@ public class DictionaryFacilitatorImpl implements DictionaryFacilitator {
// TODO: Revise the way to fusion suggestion results.
@Override
public SuggestionResults getSuggestionResults(ComposedData composedData,
- NgramContext ngramContext, long proximityInfoHandle,
+ NgramContext ngramContext, @Nonnull final Keyboard keyboard,
SettingsValuesForSuggestion settingsValuesForSuggestion, int sessionId,
- int inputStyle, KeyboardLayout keyboardLayout) {
+ int inputStyle) {
+ long proximityInfoHandle = keyboard.getProximityInfo().getNativeProximityInfo();
final DictionaryGroup[] dictionaryGroups = mDictionaryGroups;
final SuggestionResults suggestionResults = new SuggestionResults(
- SuggestedWords.MAX_SUGGESTIONS, ngramContext.isBeginningOfSentenceContext());
+ SuggestedWords.MAX_SUGGESTIONS, ngramContext.isBeginningOfSentenceContext(),
+ false /* firstSuggestionExceedsConfidenceThreshold */);
final float[] weightOfLangModelVsSpatialModel =
new float[] { Dictionary.NOT_A_WEIGHT_OF_LANG_MODEL_VS_SPATIAL_MODEL };
for (final DictionaryGroup dictionaryGroup : dictionaryGroups) {
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFactory.java b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
index 781ab06c5..49608d830 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFactory.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFactory.java
@@ -80,7 +80,7 @@ public final class DictionaryFactory {
* @param context The context to contact the dictionary provider, if possible.
* @param f A file address to the dictionary to kill.
*/
- private static void killDictionary(final Context context, final AssetFileAddress f) {
+ public static void killDictionary(final Context context, final AssetFileAddress f) {
if (f.pointsToPhysicalFile()) {
f.deleteUnderlyingFile();
// Warn the dictionary provider if the dictionary came from there.
diff --git a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
index 064d79b3c..b0fb91bec 100644
--- a/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/ExpandableBinaryDictionary.java
@@ -259,7 +259,7 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
/**
* Check whether GC is needed and run GC if required.
*/
- protected void runGCIfRequired(final boolean mindsBlockByGC) {
+ public void runGCIfRequired(final boolean mindsBlockByGC) {
asyncExecuteTaskWithWriteLock(new Runnable() {
@Override
public void run() {
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 5b62135c1..c5c7d2d2c 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -73,7 +73,6 @@ import com.android.inputmethod.latin.common.InputPointers;
import com.android.inputmethod.latin.define.DebugFlags;
import com.android.inputmethod.latin.define.ProductionFlags;
import com.android.inputmethod.latin.inputlogic.InputLogic;
-import com.android.inputmethod.latin.personalization.DictionaryDecayBroadcastReciever;
import com.android.inputmethod.latin.personalization.PersonalizationHelper;
import com.android.inputmethod.latin.settings.Settings;
import com.android.inputmethod.latin.settings.SettingsActivity;
@@ -585,7 +584,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
dictDumpFilter.addAction(DictionaryDumpBroadcastReceiver.DICTIONARY_DUMP_INTENT_ACTION);
registerReceiver(mDictionaryDumpBroadcastReceiver, dictDumpFilter);
- DictionaryDecayBroadcastReciever.setUpIntervalAlarmForDictionaryDecaying(this);
StatsUtils.onCreate(mSettings.getCurrent(), mRichImm);
}
@@ -705,7 +703,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
unregisterReceiver(mDictionaryPackInstallReceiver);
unregisterReceiver(mDictionaryDumpBroadcastReceiver);
mStatsUtilsManager.onDestroy(this /* context */);
- DictionaryDecayBroadcastReciever.cancelIntervalAlarmForDictionaryDecaying(this);
super.onDestroy();
}
@@ -1515,9 +1512,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
callback.onGetSuggestedWords(SuggestedWords.getEmptyInstance());
return;
}
- mInputLogic.getSuggestedWords(mSettings.getCurrent(), keyboard.getProximityInfo(),
- mKeyboardSwitcher.getKeyboardShiftMode(), inputStyle, sequenceNumber, callback,
- keyboard.getKeyboardLayout());
+ mInputLogic.getSuggestedWords(mSettings.getCurrent(), keyboard,
+ mKeyboardSwitcher.getKeyboardShiftMode(), inputStyle, sequenceNumber, callback);
}
@Override
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index 832fcbcb0..f4680fc88 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -20,8 +20,7 @@ import android.text.TextUtils;
import static com.android.inputmethod.latin.define.DecoderSpecificConstants.SHOULD_AUTO_CORRECT_USING_NON_WHITE_LISTED_SUGGESTION;
-import com.android.inputmethod.keyboard.KeyboardLayout;
-import com.android.inputmethod.keyboard.ProximityInfo;
+import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.common.Constants;
import com.android.inputmethod.latin.common.StringUtils;
@@ -97,19 +96,17 @@ public final class Suggest {
}
public void getSuggestedWords(final WordComposer wordComposer,
- final NgramContext ngramContext, final ProximityInfo proximityInfo,
+ final NgramContext ngramContext, final Keyboard keyboard,
final SettingsValuesForSuggestion settingsValuesForSuggestion,
final boolean isCorrectionEnabled, final int inputStyle, final int sequenceNumber,
- final OnGetSuggestedWordsCallback callback,
- final KeyboardLayout keyboardLayout) {
+ final OnGetSuggestedWordsCallback callback) {
if (wordComposer.isBatchMode()) {
- getSuggestedWordsForBatchInput(wordComposer, ngramContext, proximityInfo,
- settingsValuesForSuggestion, inputStyle, sequenceNumber, callback,
- keyboardLayout);
+ getSuggestedWordsForBatchInput(wordComposer, ngramContext, keyboard,
+ settingsValuesForSuggestion, inputStyle, sequenceNumber, callback);
} else {
- getSuggestedWordsForNonBatchInput(wordComposer, ngramContext, proximityInfo,
+ getSuggestedWordsForNonBatchInput(wordComposer, ngramContext, keyboard,
settingsValuesForSuggestion, inputStyle, isCorrectionEnabled,
- sequenceNumber, callback, keyboardLayout);
+ sequenceNumber, callback);
}
}
@@ -165,11 +162,10 @@ public final class Suggest {
// Retrieves suggestions for non-batch input (typing, recorrection, predictions...)
// and calls the callback function with the suggestions.
private void getSuggestedWordsForNonBatchInput(final WordComposer wordComposer,
- final NgramContext ngramContext, final ProximityInfo proximityInfo,
+ final NgramContext ngramContext, final Keyboard keyboard,
final SettingsValuesForSuggestion settingsValuesForSuggestion,
final int inputStyleIfNotPrediction, final boolean isCorrectionEnabled,
- final int sequenceNumber, final OnGetSuggestedWordsCallback callback,
- final KeyboardLayout keyboardLayout) {
+ final int sequenceNumber, final OnGetSuggestedWordsCallback callback) {
final String typedWordString = wordComposer.getTypedWord();
final int trailingSingleQuotesCount =
StringUtils.getTrailingSingleQuotesCount(typedWordString);
@@ -178,9 +174,8 @@ public final class Suggest {
: typedWordString;
final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults(
- wordComposer.getComposedDataSnapshot(), ngramContext,
- proximityInfo.getNativeProximityInfo(), settingsValuesForSuggestion,
- SESSION_ID_TYPING, inputStyleIfNotPrediction, keyboardLayout);
+ wordComposer.getComposedDataSnapshot(), ngramContext, keyboard,
+ settingsValuesForSuggestion, SESSION_ID_TYPING, inputStyleIfNotPrediction);
final Locale mostProbableLocale = mDictionaryFacilitator.getMostProbableLocale();
final ArrayList<SuggestedWordInfo> suggestionsContainer =
getTransformedSuggestedWordInfoList(wordComposer, suggestionResults,
@@ -215,7 +210,8 @@ public final class Suggest {
}
}
- SuggestedWordInfo.removeDups(typedWordString, suggestionsContainer);
+ final int firstOcurrenceOfTypedWordInSuggestions =
+ SuggestedWordInfo.removeDups(typedWordString, suggestionsContainer);
final SuggestedWordInfo whitelistedWordInfo =
getWhitelistedWordInfoOrNull(suggestionsContainer);
@@ -278,7 +274,8 @@ public final class Suggest {
hasAutoCorrection = false;
} else {
final SuggestedWordInfo firstSuggestion = suggestionResults.first();
- if (suggestionResults.mAutocorrectRecommendation) {
+ if (suggestionResults.mFirstSuggestionExceedsConfidenceThreshold
+ && firstOcurrenceOfTypedWordInSuggestions != 0) {
hasAutoCorrection = true;
} else if (!AutoCorrectionUtils.suggestionExceedsThreshold(
firstSuggestion, consideredWord, mAutoCorrectionThreshold)) {
@@ -319,12 +316,12 @@ public final class Suggest {
} else {
inputStyle = inputStyleIfNotPrediction;
}
+
+ final boolean isTypedWordValid = firstOcurrenceOfTypedWordInSuggestions > -1
+ || (!resultsArePredictions && !allowsToBeAutoCorrected);
callback.onGetSuggestedWords(new SuggestedWords(suggestionsList,
suggestionResults.mRawSuggestions, typedWordInfo,
- // TODO: this first argument is lying. If this is a whitelisted word which is an
- // actual word, it says typedWordValid = false, which looks wrong. We should either
- // rename the attribute or change the value.
- !resultsArePredictions && !allowsToBeAutoCorrected /* typedWordValid */,
+ isTypedWordValid,
hasAutoCorrection /* willAutoCorrect */,
false /* isObsoleteSuggestions */, inputStyle, sequenceNumber));
}
@@ -346,15 +343,13 @@ public final class Suggest {
// Retrieves suggestions for the batch input
// and calls the callback function with the suggestions.
private void getSuggestedWordsForBatchInput(final WordComposer wordComposer,
- final NgramContext ngramContext, final ProximityInfo proximityInfo,
+ final NgramContext ngramContext, final Keyboard keyboard,
final SettingsValuesForSuggestion settingsValuesForSuggestion,
final int inputStyle, final int sequenceNumber,
- final OnGetSuggestedWordsCallback callback,
- final KeyboardLayout keyboardLayout) {
+ final OnGetSuggestedWordsCallback callback) {
final SuggestionResults suggestionResults = mDictionaryFacilitator.getSuggestionResults(
- wordComposer.getComposedDataSnapshot(), ngramContext,
- proximityInfo.getNativeProximityInfo(), settingsValuesForSuggestion,
- SESSION_ID_GESTURE, inputStyle, keyboardLayout);
+ wordComposer.getComposedDataSnapshot(), ngramContext, keyboard,
+ settingsValuesForSuggestion, SESSION_ID_GESTURE, inputStyle);
// For transforming words that don't come from a dictionary, because it's our best bet
final Locale defaultLocale = mDictionaryFacilitator.getMostProbableLocale();
final ArrayList<SuggestedWordInfo> suggestionsContainer =
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index 913b63a61..3816c0870 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -17,6 +17,7 @@
package com.android.inputmethod.latin;
import android.text.TextUtils;
+import android.util.Log;
import android.view.inputmethod.CompletionInfo;
import com.android.inputmethod.annotations.UsedForTesting;
@@ -375,31 +376,45 @@ public class SuggestedWords {
return mWord + " (" + mDebugString + ")";
}
- // This will always remove the higher index if a duplicate is found.
- public static void removeDups(@Nullable final String typedWord,
- @Nonnull ArrayList<SuggestedWordInfo> candidates) {
+ /**
+ * This will always remove the higher index if a duplicate is found.
+ *
+ * @return position of typed word in the candidate list
+ */
+ public static int removeDups(
+ @Nullable final String typedWord,
+ @Nonnull final ArrayList<SuggestedWordInfo> candidates) {
if (candidates.isEmpty()) {
- return;
+ return -1;
}
+ int firstOccurrenceOfWord = -1;
if (!TextUtils.isEmpty(typedWord)) {
- removeSuggestedWordInfoFromList(typedWord, candidates, -1 /* startIndexExclusive */);
+ firstOccurrenceOfWord = removeSuggestedWordInfoFromList(
+ typedWord, candidates, -1 /* startIndexExclusive */);
}
for (int i = 0; i < candidates.size(); ++i) {
- removeSuggestedWordInfoFromList(candidates.get(i).mWord, candidates,
- i /* startIndexExclusive */);
+ removeSuggestedWordInfoFromList(
+ candidates.get(i).mWord, candidates, i /* startIndexExclusive */);
}
+ return firstOccurrenceOfWord;
}
- private static void removeSuggestedWordInfoFromList(
- @Nonnull final String word, @Nonnull final ArrayList<SuggestedWordInfo> candidates,
+ private static int removeSuggestedWordInfoFromList(
+ @Nonnull final String word,
+ @Nonnull final ArrayList<SuggestedWordInfo> candidates,
final int startIndexExclusive) {
+ int firstOccurrenceOfWord = -1;
for (int i = startIndexExclusive + 1; i < candidates.size(); ++i) {
final SuggestedWordInfo previous = candidates.get(i);
if (word.equals(previous.mWord)) {
+ if (firstOccurrenceOfWord == -1) {
+ firstOccurrenceOfWord = i;
+ }
candidates.remove(i);
--i;
}
}
+ return firstOccurrenceOfWord;
}
}
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index 57aa59190..7907aaa16 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -32,9 +32,8 @@ import android.view.inputmethod.EditorInfo;
import com.android.inputmethod.compat.SuggestionSpanUtils;
import com.android.inputmethod.event.Event;
import com.android.inputmethod.event.InputTransaction;
-import com.android.inputmethod.keyboard.KeyboardLayout;
+import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.KeyboardSwitcher;
-import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.DictionaryFacilitator;
import com.android.inputmethod.latin.LastComposedWord;
@@ -2165,9 +2164,8 @@ public final class InputLogic {
}
public void getSuggestedWords(final SettingsValues settingsValues,
- final ProximityInfo proximityInfo, final int keyboardShiftMode, final int inputStyle,
- final int sequenceNumber, final OnGetSuggestedWordsCallback callback,
- final KeyboardLayout keyboardLayout) {
+ final Keyboard keyboard, final int keyboardShiftMode, final int inputStyle,
+ final int sequenceNumber, final OnGetSuggestedWordsCallback callback) {
mWordComposer.adviseCapitalizedModeBeforeFetchingSuggestions(
getActualCapsMode(settingsValues, keyboardShiftMode));
mSuggest.getSuggestedWords(mWordComposer,
@@ -2177,11 +2175,11 @@ public final class InputLogic {
// a word, it's whatever is *before* the half-committed word in the buffer,
// hence 2; if we aren't, we should just skip whitespace if any, so 1.
mWordComposer.isComposingWord() ? 2 : 1),
- proximityInfo,
+ keyboard,
new SettingsValuesForSuggestion(settingsValues.mBlockPotentiallyOffensive,
settingsValues.mPhraseGestureEnabled),
settingsValues.mAutoCorrectionEnabledPerUserSettings,
- inputStyle, sequenceNumber, callback, keyboardLayout);
+ inputStyle, sequenceNumber, callback);
}
/**
diff --git a/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java b/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java
deleted file mode 100644
index 78b51d9f4..000000000
--- a/java/src/com/android/inputmethod/latin/personalization/DecayingExpandableBinaryDictionaryBase.java
+++ /dev/null
@@ -1,85 +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.personalization;
-
-import android.content.Context;
-
-import com.android.inputmethod.latin.Dictionary;
-import com.android.inputmethod.latin.ExpandableBinaryDictionary;
-import com.android.inputmethod.latin.makedict.DictionaryHeader;
-
-import java.io.File;
-import java.util.Locale;
-import java.util.Map;
-
-/**
- * This class is a base class of a dictionary that supports decaying for the personalized language
- * model.
- */
-public abstract class DecayingExpandableBinaryDictionaryBase extends ExpandableBinaryDictionary {
- private static final boolean DBG_DUMP_ON_CLOSE = false;
-
- /** Any pair being typed or picked */
- public static final int FREQUENCY_FOR_TYPED = 2;
-
- public static final int FREQUENCY_FOR_WORDS_IN_DICTS = FREQUENCY_FOR_TYPED;
- public static final int FREQUENCY_FOR_WORDS_NOT_IN_DICTS = Dictionary.NOT_A_PROBABILITY;
-
- protected DecayingExpandableBinaryDictionaryBase(final Context context,
- final String dictName, final Locale locale, final String dictionaryType,
- final File dictFile) {
- super(context, dictName, locale, dictionaryType, dictFile);
- if (mLocale != null && mLocale.toString().length() > 1) {
- reloadDictionaryIfRequired();
- }
- }
-
- @Override
- public void close() {
- if (DBG_DUMP_ON_CLOSE) {
- dumpAllWordsForDebug();
- }
- // Flush pending writes.
- asyncFlushBinaryDictionary();
- super.close();
- }
-
- @Override
- protected Map<String, String> getHeaderAttributeMap() {
- final Map<String, String> attributeMap = super.getHeaderAttributeMap();
- attributeMap.put(DictionaryHeader.USES_FORGETTING_CURVE_KEY,
- DictionaryHeader.ATTRIBUTE_VALUE_TRUE);
- attributeMap.put(DictionaryHeader.HAS_HISTORICAL_INFO_KEY,
- DictionaryHeader.ATTRIBUTE_VALUE_TRUE);
- return attributeMap;
- }
-
- @Override
- protected void loadInitialContentsLocked() {
- // No initial contents.
- }
-
- /* package */ void runGCIfRequired() {
- runGCIfRequired(false /* mindsBlockByGC */);
- }
-
- @Override
- public boolean isValidWord(final String word) {
- // Strings out of this dictionary should not be considered existing words.
- return false;
- }
-}
diff --git a/java/src/com/android/inputmethod/latin/personalization/DictionaryDecayBroadcastReciever.java b/java/src/com/android/inputmethod/latin/personalization/DictionaryDecayBroadcastReciever.java
deleted file mode 100644
index 0c5e5d010..000000000
--- a/java/src/com/android/inputmethod/latin/personalization/DictionaryDecayBroadcastReciever.java
+++ /dev/null
@@ -1,89 +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.personalization;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * Broadcast receiver for periodically updating decaying dictionaries.
- */
-public class DictionaryDecayBroadcastReciever extends BroadcastReceiver {
- /**
- * The root domain for the personalization.
- */
- private static final String PERSONALIZATION_DOMAIN =
- "com.android.inputmethod.latin.personalization";
-
- /**
- * The action of the intent to tell the time to decay dictionaries.
- */
- private static final String DICTIONARY_DECAY_INTENT_ACTION =
- PERSONALIZATION_DOMAIN + ".DICT_DECAY";
-
- /**
- * Interval to update for decaying dictionaries.
- */
- static final long DICTIONARY_DECAY_INTERVAL_IN_MILLIS = TimeUnit.MINUTES.toMillis(60);
-
- private static PendingIntent getPendingIntentForDictionaryDecay(final Context context) {
- final Intent updateIntent = new Intent(DICTIONARY_DECAY_INTENT_ACTION);
- updateIntent.setClass(context, DictionaryDecayBroadcastReciever.class);
- return PendingIntent.getBroadcast(context, 0 /* requestCode */,
- updateIntent, PendingIntent.FLAG_CANCEL_CURRENT);
- }
-
- /**
- * Set up interval alarm for dynamic dictionaries.
- */
- public static void setUpIntervalAlarmForDictionaryDecaying(final Context context) {
- final AlarmManager alarmManager =
- (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
- if (null == alarmManager) {
- return;
- }
- final long alarmTriggerTimeInMillis =
- System.currentTimeMillis() + DICTIONARY_DECAY_INTERVAL_IN_MILLIS;
- alarmManager.setInexactRepeating(AlarmManager.RTC, alarmTriggerTimeInMillis,
- DICTIONARY_DECAY_INTERVAL_IN_MILLIS, getPendingIntentForDictionaryDecay(context));
- }
-
- /**
- * Cancel interval alarm that has been set up.
- */
- public static void cancelIntervalAlarmForDictionaryDecaying(final Context context) {
- final AlarmManager alarmManager =
- (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
- if (null == alarmManager) {
- return;
- }
- alarmManager.cancel(getPendingIntentForDictionaryDecay(context));
- }
-
- @Override
- public void onReceive(final Context context, final Intent intent) {
- final String action = intent.getAction();
- if (action.equals(DICTIONARY_DECAY_INTENT_ACTION)) {
- PersonalizationHelper.runGCOnAllOpenedUserHistoryDictionaries();
- }
- }
-}
diff --git a/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java b/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java
index 1c1cb4f95..298e46c0a 100644
--- a/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java
+++ b/java/src/com/android/inputmethod/latin/personalization/PersonalizationHelper.java
@@ -26,7 +26,6 @@ import java.io.FilenameFilter;
import java.lang.ref.SoftReference;
import java.util.Locale;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.TimeUnit;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -68,60 +67,28 @@ public class PersonalizationHelper {
}
}
- private static int sCurrentTimestampForTesting = 0;
- public static void currentTimeChangedForTesting(final int currentTimestamp) {
- if (TimeUnit.MILLISECONDS.toSeconds(
- DictionaryDecayBroadcastReciever.DICTIONARY_DECAY_INTERVAL_IN_MILLIS)
- < currentTimestamp - sCurrentTimestampForTesting) {
- runGCOnAllOpenedUserHistoryDictionaries();
- }
- }
-
- public static void runGCOnAllOpenedUserHistoryDictionaries() {
- runGCOnAllDictionariesIfRequired(sLangUserHistoryDictCache);
- }
-
- private static <T extends DecayingExpandableBinaryDictionaryBase>
- void runGCOnAllDictionariesIfRequired(
- final ConcurrentHashMap<String, SoftReference<T>> dictionaryMap) {
- for (final ConcurrentHashMap.Entry<String, SoftReference<T>> entry
- : dictionaryMap.entrySet()) {
- final DecayingExpandableBinaryDictionaryBase dict = entry.getValue().get();
- if (dict != null) {
- dict.runGCIfRequired();
- } else {
- dictionaryMap.remove(entry.getKey());
- }
- }
- }
-
public static void removeAllUserHistoryDictionaries(final Context context) {
- removeAllDictionaries(context, sLangUserHistoryDictCache,
- UserHistoryDictionary.NAME);
- }
-
- private static <T extends DecayingExpandableBinaryDictionaryBase> void removeAllDictionaries(
- final Context context, final ConcurrentHashMap<String, SoftReference<T>> dictionaryMap,
- final String dictNamePrefix) {
- synchronized (dictionaryMap) {
- for (final ConcurrentHashMap.Entry<String, SoftReference<T>> entry
- : dictionaryMap.entrySet()) {
+ synchronized (sLangUserHistoryDictCache) {
+ for (final ConcurrentHashMap.Entry<String, SoftReference<UserHistoryDictionary>> entry
+ : sLangUserHistoryDictCache.entrySet()) {
if (entry.getValue() != null) {
- final DecayingExpandableBinaryDictionaryBase dict = entry.getValue().get();
+ final UserHistoryDictionary dict = entry.getValue().get();
if (dict != null) {
dict.clear();
}
}
}
- dictionaryMap.clear();
+ sLangUserHistoryDictCache.clear();
final File filesDir = context.getFilesDir();
if (filesDir == null) {
Log.e(TAG, "context.getFilesDir() returned null.");
return;
}
- if (!FileUtils.deleteFilteredFiles(filesDir, new DictFilter(dictNamePrefix))) {
- Log.e(TAG, "Cannot remove all existing dictionary files. filesDir: "
- + filesDir.getAbsolutePath() + ", dictNamePrefix: " + dictNamePrefix);
+ final boolean filesDeleted = FileUtils.deleteFilteredFiles(
+ filesDir, new DictFilter(UserHistoryDictionary.NAME));
+ if (!filesDeleted) {
+ Log.e(TAG, "Cannot remove dictionary files. filesDir: " + filesDir.getAbsolutePath()
+ + ", dictNamePrefix: " + UserHistoryDictionary.NAME);
}
}
}
diff --git a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java
index b6286b203..54ee68d65 100644
--- a/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java
+++ b/java/src/com/android/inputmethod/latin/personalization/UserHistoryDictionary.java
@@ -25,9 +25,11 @@ import com.android.inputmethod.latin.ExpandableBinaryDictionary;
import com.android.inputmethod.latin.NgramContext;
import com.android.inputmethod.latin.define.DecoderSpecificConstants;
import com.android.inputmethod.latin.define.ProductionFlags;
+import com.android.inputmethod.latin.makedict.DictionaryHeader;
import java.io.File;
import java.util.Locale;
+import java.util.Map;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -37,17 +39,16 @@ import javax.annotation.Nullable;
* auto-correction cancellation or manual picks. This allows the keyboard to adapt to the
* typist over time.
*/
-public class UserHistoryDictionary extends DecayingExpandableBinaryDictionaryBase {
+public class UserHistoryDictionary extends ExpandableBinaryDictionary {
static final String NAME = UserHistoryDictionary.class.getSimpleName();
// TODO: Make this constructor private
UserHistoryDictionary(final Context context, final Locale locale,
@Nullable final String account) {
- super(context,
- getUserHistoryDictName(NAME, locale, null /* dictFile */, account),
- locale,
- Dictionary.TYPE_USER_HISTORY,
- null /* dictFile */);
+ super(context, getUserHistoryDictName(NAME, locale, null /* dictFile */, account), locale, Dictionary.TYPE_USER_HISTORY, null);
+ if (mLocale != null && mLocale.toString().length() > 1) {
+ reloadDictionaryIfRequired();
+ }
}
/**
@@ -103,4 +104,32 @@ public class UserHistoryDictionary extends DecayingExpandableBinaryDictionaryBas
userHistoryDictionary.updateEntriesForWord(ngramContext, word,
isValid, 1 /* count */, timestamp);
}
+
+ @Override
+ public void close() {
+ // Flush pending writes.
+ asyncFlushBinaryDictionary();
+ super.close();
+ }
+
+ @Override
+ protected Map<String, String> getHeaderAttributeMap() {
+ final Map<String, String> attributeMap = super.getHeaderAttributeMap();
+ attributeMap.put(DictionaryHeader.USES_FORGETTING_CURVE_KEY,
+ DictionaryHeader.ATTRIBUTE_VALUE_TRUE);
+ attributeMap.put(DictionaryHeader.HAS_HISTORICAL_INFO_KEY,
+ DictionaryHeader.ATTRIBUTE_VALUE_TRUE);
+ return attributeMap;
+ }
+
+ @Override
+ protected void loadInitialContentsLocked() {
+ // No initial contents.
+ }
+
+ @Override
+ public boolean isValidWord(final String word) {
+ // Strings out of this dictionary should not be considered existing words.
+ return false;
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
index 9822c5725..f04f093f0 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
@@ -28,9 +28,7 @@ import android.util.Log;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.KeyboardId;
-import com.android.inputmethod.keyboard.KeyboardLayout;
import com.android.inputmethod.keyboard.KeyboardLayoutSet;
-import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.DictionaryFacilitator;
import com.android.inputmethod.latin.DictionaryFacilitatorLruCache;
import com.android.inputmethod.latin.NgramContext;
@@ -48,6 +46,8 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Semaphore;
+import javax.annotation.Nonnull;
+
/**
* Service for spell checking, using LatinIME's dictionaries and mechanisms.
*/
@@ -193,7 +193,7 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
public SuggestionResults getSuggestionResults(final Locale locale,
final ComposedData composedData, final NgramContext ngramContext,
- final ProximityInfo proximityInfo, final KeyboardLayout keyboardLayout) {
+ @Nonnull final Keyboard keyboard) {
Integer sessionId = null;
mSemaphore.acquireUninterruptibly();
try {
@@ -201,8 +201,8 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
DictionaryFacilitator dictionaryFacilitatorForLocale =
mDictionaryFacilitatorCache.get(locale);
return dictionaryFacilitatorForLocale.getSuggestionResults(composedData, ngramContext,
- proximityInfo.getNativeProximityInfo(), mSettingsValuesForSuggestion,
- sessionId, SuggestedWords.INPUT_STYLE_TYPING, keyboardLayout);
+ keyboard, mSettingsValuesForSuggestion,
+ sessionId, SuggestedWords.INPUT_STYLE_TYPING);
} finally {
if (sessionId != null) {
mSessionIdPool.add(sessionId);
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
index 1c43a4b71..5c1915c6c 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
@@ -29,18 +29,11 @@ import android.view.textservice.TextInfo;
import com.android.inputmethod.compat.SuggestionsInfoCompatUtils;
import com.android.inputmethod.keyboard.Keyboard;
-import com.android.inputmethod.keyboard.KeyboardLayout;
-import com.android.inputmethod.keyboard.ProximityInfo;
import com.android.inputmethod.latin.NgramContext;
-import com.android.inputmethod.latin.SuggestedWords;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.WordComposer;
-import com.android.inputmethod.latin.common.ComposedData;
import com.android.inputmethod.latin.common.Constants;
-import com.android.inputmethod.latin.common.CoordinateUtils;
-import com.android.inputmethod.latin.common.InputPointers;
import com.android.inputmethod.latin.common.LocaleUtils;
-import com.android.inputmethod.latin.common.ResizableIntArray;
import com.android.inputmethod.latin.common.StringUtils;
import com.android.inputmethod.latin.utils.BinaryDictionaryUtils;
import com.android.inputmethod.latin.utils.ScriptUtils;
@@ -272,26 +265,20 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session {
false /* reportAsTypo */);
}
final Keyboard keyboard = mService.getKeyboardForLocale(mLocale);
+ if (null == keyboard) {
+ Log.d(TAG, "No keyboard for locale: " + mLocale);
+ // If there is no keyboard for this locale, don't do any spell-checking.
+ return AndroidSpellCheckerService.getNotInDictEmptySuggestions(
+ false /* reportAsTypo */);
+ }
final WordComposer composer = new WordComposer();
final int[] codePoints = StringUtils.toCodePointArray(text);
final int[] coordinates;
- final ProximityInfo proximityInfo;
- final KeyboardLayout keyboardLayout;
- if (null == keyboard) {
- coordinates = CoordinateUtils.newCoordinateArray(codePoints.length,
- Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE);
- proximityInfo = null;
- keyboardLayout = null;
- } else {
- coordinates = keyboard.getCoordinates(codePoints);
- proximityInfo = keyboard.getProximityInfo();
- keyboardLayout = keyboard.getKeyboardLayout();
- }
+ coordinates = keyboard.getCoordinates(codePoints);
composer.setComposingWord(codePoints, coordinates);
// TODO: Don't gather suggestions if the limit is <= 0 unless necessary
final SuggestionResults suggestionResults = mService.getSuggestionResults(
- mLocale, composer.getComposedDataSnapshot(), ngramContext, proximityInfo,
- keyboardLayout);
+ mLocale, composer.getComposedDataSnapshot(), ngramContext, keyboard);
final Result result = getResult(capitalizeType, mLocale, suggestionsLimit,
mService.getRecommendedThreshold(), text, suggestionResults);
isInDict = isInDictForAnyCapitalization(text, capitalizeType);
diff --git a/java/src/com/android/inputmethod/latin/utils/BinaryDictionaryUtils.java b/java/src/com/android/inputmethod/latin/utils/BinaryDictionaryUtils.java
index 23ffde2a2..892b967c4 100644
--- a/java/src/com/android/inputmethod/latin/utils/BinaryDictionaryUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/BinaryDictionaryUtils.java
@@ -21,7 +21,6 @@ import com.android.inputmethod.latin.BinaryDictionary;
import com.android.inputmethod.latin.common.StringUtils;
import com.android.inputmethod.latin.makedict.DictionaryHeader;
import com.android.inputmethod.latin.makedict.UnsupportedFormatException;
-import com.android.inputmethod.latin.personalization.PersonalizationHelper;
import java.io.File;
import java.io.IOException;
@@ -123,8 +122,6 @@ public final class BinaryDictionaryUtils {
*/
@UsedForTesting
public static int setCurrentTimeForTest(final int currentTime) {
- final int currentNativeTimestamp = setCurrentTimeForTestNative(currentTime);
- PersonalizationHelper.currentTimeChangedForTesting(currentNativeTimestamp);
- return currentNativeTimestamp;
+ return setCurrentTimeForTestNative(currentTime);
}
}
diff --git a/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java b/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java
index 10e3994b6..981355115 100644
--- a/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java
+++ b/java/src/com/android/inputmethod/latin/utils/SuggestionResults.java
@@ -33,21 +33,18 @@ public final class SuggestionResults extends TreeSet<SuggestedWordInfo> {
// TODO: Instead of a boolean , we may want to include the context of this suggestion results,
// such as {@link NgramContext}.
public final boolean mIsBeginningOfSentence;
- public final boolean mAutocorrectRecommendation;
+ public final boolean mFirstSuggestionExceedsConfidenceThreshold;
private final int mCapacity;
- public SuggestionResults(final int capacity, final boolean isBeginningOfSentence) {
- this(sSuggestedWordInfoComparator, capacity, isBeginningOfSentence, false);
- }
-
public SuggestionResults(final int capacity, final boolean isBeginningOfSentence,
- final boolean autocorrectRecommendation) {
+ final boolean firstSuggestionExceedsConfidenceThreshold) {
this(sSuggestedWordInfoComparator, capacity, isBeginningOfSentence,
- autocorrectRecommendation);
+ firstSuggestionExceedsConfidenceThreshold);
}
private SuggestionResults(final Comparator<SuggestedWordInfo> comparator, final int capacity,
- final boolean isBeginningOfSentence, final boolean autocorrectRecommendation) {
+ final boolean isBeginningOfSentence,
+ final boolean firstSuggestionExceedsConfidenceThreshold) {
super(comparator);
mCapacity = capacity;
if (ProductionFlags.INCLUDE_RAW_SUGGESTIONS) {
@@ -56,7 +53,7 @@ public final class SuggestionResults extends TreeSet<SuggestedWordInfo> {
mRawSuggestions = null;
}
mIsBeginningOfSentence = isBeginningOfSentence;
- mAutocorrectRecommendation = autocorrectRecommendation;
+ mFirstSuggestionExceedsConfidenceThreshold = firstSuggestionExceedsConfidenceThreshold;
}
@Override