aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod/latin/spellcheck
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com/android/inputmethod/latin/spellcheck')
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java22
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java17
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/DictAndKeyboard.java9
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java4
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerSettingsFragment.java2
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/SynchronouslyLoadedContactsBinaryDictionary.java54
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/SynchronouslyLoadedUserBinaryDictionary.java59
7 files changed, 140 insertions, 27 deletions
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
index 503b18b1b..65ebcf5f1 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
@@ -33,10 +33,9 @@ import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.DictionaryCollection;
import com.android.inputmethod.latin.DictionaryFactory;
import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.SynchronouslyLoadedContactsBinaryDictionary;
-import com.android.inputmethod.latin.SynchronouslyLoadedUserBinaryDictionary;
import com.android.inputmethod.latin.UserBinaryDictionary;
import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils;
+import com.android.inputmethod.latin.utils.BinaryDictionaryUtils;
import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.LocaleUtils;
import com.android.inputmethod.latin.utils.StringUtils;
@@ -267,6 +266,7 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
// if it doesn't. See documentation for binarySearch.
final int insertIndex = positionIndex >= 0 ? positionIndex : -positionIndex - 1;
+ // Weak <- insertIndex == 0, ..., insertIndex == mLength -> Strong
if (insertIndex == 0 && mLength >= mMaxLength) {
// In the future, we may want to keep track of the best suggestion score even if
// we are asked for 0 suggestions. In this case, we can use the following
@@ -284,11 +284,6 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
// }
return true;
}
- if (insertIndex >= mMaxLength) {
- // We found a suggestion, but its score is too weak to be kept considering
- // the suggestion limit.
- return true;
- }
final String wordString = new String(word, wordOffset, wordLength);
if (mLength < mMaxLength) {
@@ -296,12 +291,13 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
++mLength;
System.arraycopy(mScores, insertIndex, mScores, insertIndex + 1, copyLen);
mSuggestions.add(insertIndex, wordString);
+ mScores[insertIndex] = score;
} else {
- System.arraycopy(mScores, 1, mScores, 0, insertIndex);
+ System.arraycopy(mScores, 1, mScores, 0, insertIndex - 1);
mSuggestions.add(insertIndex, wordString);
mSuggestions.remove(0);
+ mScores[insertIndex - 1] = score;
}
- mScores[insertIndex] = score;
return true;
}
@@ -320,7 +316,7 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
hasRecommendedSuggestions = false;
} else {
gatheredSuggestions = EMPTY_STRING_ARRAY;
- final float normalizedScore = BinaryDictionary.calcNormalizedScore(
+ final float normalizedScore = BinaryDictionaryUtils.calcNormalizedScore(
mOriginalText, mBestSuggestion, mBestScore);
hasRecommendedSuggestions = (normalizedScore > mRecommendedThreshold);
}
@@ -355,7 +351,7 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
final int bestScore = mScores[mLength - 1];
final String bestSuggestion = mSuggestions.get(0);
final float normalizedScore =
- BinaryDictionary.calcNormalizedScore(
+ BinaryDictionaryUtils.calcNormalizedScore(
mOriginalText, bestSuggestion.toString(), bestScore);
hasRecommendedSuggestions = (normalizedScore > mRecommendedThreshold);
if (DBG) {
@@ -383,6 +379,8 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
new Thread("spellchecker_close_dicts") {
@Override
public void run() {
+ // Contacts dictionary can be closed multiple times here. If the dictionary is
+ // already closed, extra closings are no-ops, so it's safe.
for (DictionaryPool pool : oldPools.values()) {
pool.close();
}
@@ -428,7 +426,7 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
final String localeStr = locale.toString();
UserBinaryDictionary userDictionary = mUserDictionaries.get(localeStr);
if (null == userDictionary) {
- userDictionary = new SynchronouslyLoadedUserBinaryDictionary(this, localeStr, true);
+ userDictionary = new SynchronouslyLoadedUserBinaryDictionary(this, locale, true);
mUserDictionaries.put(localeStr, userDictionary);
}
dictionaryCollection.addDictionary(userDictionary);
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
index d6e5b75ad..69d092751 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidWordLevelSpellCheckerSession.java
@@ -28,11 +28,13 @@ import android.view.textservice.SuggestionsInfo;
import android.view.textservice.TextInfo;
import com.android.inputmethod.compat.SuggestionsInfoCompatUtils;
+import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
import com.android.inputmethod.latin.WordComposer;
import com.android.inputmethod.latin.spellcheck.AndroidSpellCheckerService.SuggestionsGatherer;
+import com.android.inputmethod.latin.utils.CoordinateUtils;
import com.android.inputmethod.latin.utils.LocaleUtils;
import com.android.inputmethod.latin.utils.StringUtils;
@@ -312,16 +314,21 @@ public abstract class AndroidWordLevelSpellCheckerSession extends Session {
false /* reportAsTypo */);
}
final WordComposer composer = new WordComposer();
- final int length = text.length();
- for (int i = 0; i < length; i = text.offsetByCodePoints(i, 1)) {
- final int codePoint = text.codePointAt(i);
- composer.addKeyInfo(codePoint, dictInfo.getKeyboard(codePoint));
+ final int[] codePoints = StringUtils.toCodePointArray(text);
+ final int[] coordinates;
+ if (null == dictInfo.mKeyboard) {
+ coordinates = CoordinateUtils.newCoordinateArray(codePoints.length,
+ Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE);
+ } else {
+ coordinates = dictInfo.mKeyboard.getCoordinates(codePoints);
}
+ composer.setComposingWord(codePoints, coordinates, null /* previousWord */);
// TODO: make a spell checker option to block offensive words or not
final ArrayList<SuggestedWordInfo> suggestions =
dictInfo.mDictionary.getSuggestions(composer, prevWord,
dictInfo.getProximityInfo(), true /* blockOffensiveWords */,
- null /* additionalFeaturesOptions */);
+ null /* additionalFeaturesOptions */,
+ null /* inOutLanguageWeight */);
if (suggestions != null) {
for (final SuggestedWordInfo suggestion : suggestions) {
final String suggestionStr = suggestion.mWord;
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/DictAndKeyboard.java b/java/src/com/android/inputmethod/latin/spellcheck/DictAndKeyboard.java
index b77f3e2c5..1ffe50681 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/DictAndKeyboard.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/DictAndKeyboard.java
@@ -27,7 +27,7 @@ import com.android.inputmethod.keyboard.ProximityInfo;
*/
public final class DictAndKeyboard {
public final Dictionary mDictionary;
- private final Keyboard mKeyboard;
+ public final Keyboard mKeyboard;
private final Keyboard mManualShiftedKeyboard;
public DictAndKeyboard(
@@ -43,13 +43,6 @@ public final class DictAndKeyboard {
keyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED);
}
- public Keyboard getKeyboard(final int codePoint) {
- if (mKeyboard == null) {
- return null;
- }
- return mKeyboard.getKey(codePoint) != null ? mKeyboard : mManualShiftedKeyboard;
- }
-
public ProximityInfo getProximityInfo() {
return mKeyboard == null ? null : mKeyboard.getProximityInfo();
}
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java b/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java
index a0aed2829..c99264347 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/DictionaryPool.java
@@ -49,10 +49,12 @@ public final class DictionaryPool extends LinkedBlockingQueue<DictAndKeyboard> {
final static ArrayList<SuggestedWordInfo> noSuggestions = CollectionUtils.newArrayList();
private final static DictAndKeyboard dummyDict = new DictAndKeyboard(
new Dictionary(Dictionary.TYPE_MAIN) {
+ // TODO: this dummy dictionary should be a singleton in the Dictionary class.
@Override
public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer composer,
final String prevWord, final ProximityInfo proximityInfo,
- final boolean blockOffensiveWords, final int[] additionalFeaturesOptions) {
+ final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
+ final float[] inOutLanguageWeight) {
return noSuggestions;
}
@Override
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerSettingsFragment.java b/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerSettingsFragment.java
index 999ca775b..186dafd29 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/SpellCheckerSettingsFragment.java
@@ -39,7 +39,7 @@ public final class SpellCheckerSettingsFragment extends PreferenceFragment {
addPreferencesFromResource(R.xml.spell_checker_settings);
final PreferenceScreen preferenceScreen = getPreferenceScreen();
if (preferenceScreen != null) {
- preferenceScreen.setTitle(ApplicationUtils.getAcitivityTitleResId(
+ preferenceScreen.setTitle(ApplicationUtils.getActivityTitleResId(
getActivity(), SpellCheckerSettingsActivity.class));
}
}
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/SynchronouslyLoadedContactsBinaryDictionary.java b/java/src/com/android/inputmethod/latin/spellcheck/SynchronouslyLoadedContactsBinaryDictionary.java
new file mode 100644
index 000000000..a694bf47d
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/spellcheck/SynchronouslyLoadedContactsBinaryDictionary.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2012 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.spellcheck;
+
+import android.content.Context;
+
+import com.android.inputmethod.keyboard.ProximityInfo;
+import com.android.inputmethod.latin.ContactsBinaryDictionary;
+import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+import com.android.inputmethod.latin.WordComposer;
+
+import java.util.ArrayList;
+import java.util.Locale;
+
+public final class SynchronouslyLoadedContactsBinaryDictionary extends ContactsBinaryDictionary {
+ private static final String NAME = "spellcheck_contacts";
+ private final Object mLock = new Object();
+
+ public SynchronouslyLoadedContactsBinaryDictionary(final Context context, final Locale locale) {
+ super(context, locale, null /* dictFile */, NAME);
+ }
+
+ @Override
+ public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer codes,
+ final String prevWordForBigrams, final ProximityInfo proximityInfo,
+ final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
+ final float[] inOutLanguageWeight) {
+ synchronized (mLock) {
+ return super.getSuggestions(codes, prevWordForBigrams, proximityInfo,
+ blockOffensiveWords, additionalFeaturesOptions, inOutLanguageWeight);
+ }
+ }
+
+ @Override
+ public boolean isValidWord(final String word) {
+ synchronized (mLock) {
+ return super.isValidWord(word);
+ }
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/SynchronouslyLoadedUserBinaryDictionary.java b/java/src/com/android/inputmethod/latin/spellcheck/SynchronouslyLoadedUserBinaryDictionary.java
new file mode 100644
index 000000000..1a6dd5818
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/spellcheck/SynchronouslyLoadedUserBinaryDictionary.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2012 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.spellcheck;
+
+import android.content.Context;
+
+import com.android.inputmethod.keyboard.ProximityInfo;
+import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo;
+import com.android.inputmethod.latin.UserBinaryDictionary;
+import com.android.inputmethod.latin.WordComposer;
+
+import java.util.ArrayList;
+import java.util.Locale;
+
+public final class SynchronouslyLoadedUserBinaryDictionary extends UserBinaryDictionary {
+ private static final String NAME = "spellcheck_user";
+ private final Object mLock = new Object();
+
+ public SynchronouslyLoadedUserBinaryDictionary(final Context context, final Locale locale) {
+ this(context, locale, false /* alsoUseMoreRestrictiveLocales */);
+ }
+
+ public SynchronouslyLoadedUserBinaryDictionary(final Context context, final Locale locale,
+ final boolean alsoUseMoreRestrictiveLocales) {
+ super(context, locale, alsoUseMoreRestrictiveLocales, null /* dictFile */, NAME);
+ }
+
+ @Override
+ public ArrayList<SuggestedWordInfo> getSuggestions(final WordComposer codes,
+ final String prevWordForBigrams, final ProximityInfo proximityInfo,
+ final boolean blockOffensiveWords, final int[] additionalFeaturesOptions,
+ final float[] inOutLanguageWeight) {
+ synchronized (mLock) {
+ return super.getSuggestions(codes, prevWordForBigrams, proximityInfo,
+ blockOffensiveWords, additionalFeaturesOptions, inOutLanguageWeight);
+ }
+ }
+
+ @Override
+ public boolean isValidWord(final String word) {
+ synchronized (mLock) {
+ return super.isValidWord(word);
+ }
+ }
+}