Merge "Enable auto-correction only if there is a significant size main dictionary."

main
Amith Yamasani 2010-01-07 13:08:29 -08:00 committed by Android (Google) Code Review
commit a052b69b47
6 changed files with 73 additions and 28 deletions

View File

@ -38,6 +38,7 @@ using namespace android;
static jfieldID sDescriptorField;
static jfieldID sAssetManagerNativeField;
static jmethodID sAddWordMethod;
static jfieldID sDictLength;
//
// helper function to throw an exception
@ -79,6 +80,7 @@ static jint latinime_BinaryDictionary_open
}
Dictionary *dictionary = new Dictionary(dict, typedLetterMultiplier, fullWordMultiplier);
dictionary->setAsset(dictAsset);
env->SetIntField(object, sDictLength, (jint) dictAsset->getLength());
env->ReleaseStringUTFChars(resourceString, resourcePath);
return (jint) dictionary;
@ -176,6 +178,14 @@ static int registerNatives(JNIEnv *env)
}
sAssetManagerNativeField = env->GetFieldID(clazz, "mObject", "I");
// Get the field pointer for the dictionary length
clazz = env->FindClass(kClassPathName);
if (clazz == NULL) {
LOGE("Can't find %s", kClassPathName);
return -1;
}
sDictLength = env->GetFieldID(clazz, "mDictLength", "I");
return registerNativeMethods(env,
kClassPathName, gMethods, sizeof(gMethods) / sizeof(gMethods[0]));
}

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2009 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.
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="english_ime_name" msgid="7252517407088836577">"Clavier Android"</string>
</resources>

View File

@ -31,7 +31,9 @@
<Key android:keyLabel="ц"/>
<Key android:keyLabel="у"/>
<Key android:keyLabel="к"/>
<Key android:keyLabel="е"/>
<Key android:keyLabel="е"
android:popupKeyboard="@xml/kbd_popup_template"
android:popupCharacters="ё" />
<Key android:keyLabel="н"/>
<Key android:keyLabel="г"/>
<Key android:keyLabel="ш"/>
@ -40,7 +42,7 @@
<Key android:keyLabel="х"
android:keyEdgeFlags="right"/>
</Row>
<Row>
<Key android:keyLabel="ф"
android:keyEdgeFlags="left"/>

View File

@ -35,6 +35,7 @@ public class BinaryDictionary extends Dictionary {
private static final boolean ENABLE_MISSED_CHARACTERS = true;
private int mNativeDict;
private int mDictLength; // This value is set from native code, don't change the name!!!!
private int[] mInputCodes = new int[MAX_WORD_LENGTH * MAX_ALTERNATIVES];
private char[] mOutputChars = new char[MAX_WORD_LENGTH * MAX_WORDS];
private int[] mFrequencies = new int[MAX_WORDS];
@ -125,6 +126,10 @@ public class BinaryDictionary extends Dictionary {
return isValidWordNative(mNativeDict, chars, chars.length);
}
public int getSize() {
return mDictLength; // This value is initialized on the call to openNative()
}
@Override
public synchronized void close() {
if (mNativeDict != 0) {

View File

@ -126,7 +126,9 @@ public class LatinIME extends InputMethodService
private CharSequence mBestWord;
private boolean mPredictionOn;
private boolean mCompletionOn;
private boolean mHasDictionary;
private boolean mAutoSpace;
private boolean mAutoCorrectEnabled;
private boolean mAutoCorrectOn;
private boolean mCapsLock;
private boolean mVibrateOn;
@ -224,7 +226,6 @@ public class LatinIME extends InputMethodService
mSuggest.close();
}
mSuggest = new Suggest(this, R.raw.main);
mSuggest.setCorrectionMode(mCorrectionMode);
mUserDictionary = new UserDictionary(this);
if (mContactsDictionary == null) {
mContactsDictionary = new ContactsDictionary(this);
@ -236,7 +237,7 @@ public class LatinIME extends InputMethodService
mSuggest.setUserDictionary(mUserDictionary);
mSuggest.setContactsDictionary(mContactsDictionary);
mSuggest.setAutoDictionary(mAutoDictionary);
updateCorrectionMode();
mWordSeparators = mResources.getString(R.string.word_separators);
mSentenceSeparators = mResources.getString(R.string.sentence_separators);
@ -304,7 +305,7 @@ public class LatinIME extends InputMethodService
TextEntryState.newSession(this);
boolean disableAutoCorrect = false;
mInputTypeNoAutoCorrect = false;
mPredictionOn = false;
mCompletionOn = false;
mCompletions = null;
@ -353,19 +354,19 @@ public class LatinIME extends InputMethodService
// If it's a browser edit field and auto correct is not ON explicitly, then
// disable auto correction, but keep suggestions on.
if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0) {
disableAutoCorrect = true;
mInputTypeNoAutoCorrect = true;
}
}
// If NO_SUGGESTIONS is set, don't do prediction.
if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_NO_SUGGESTIONS) != 0) {
mPredictionOn = false;
disableAutoCorrect = true;
mInputTypeNoAutoCorrect = true;
}
// If it's not multiline and the autoCorrect flag is not set, then don't correct
if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0 &&
(attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE) == 0) {
disableAutoCorrect = true;
mInputTypeNoAutoCorrect = true;
}
if ((attribute.inputType&EditorInfo.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) {
mPredictionOn = false;
@ -385,17 +386,13 @@ public class LatinIME extends InputMethodService
setCandidatesViewShown(false);
if (mCandidateView != null) mCandidateView.setSuggestions(null, false, false, false);
loadSettings();
// Override auto correct
if (disableAutoCorrect) {
mAutoCorrectOn = false;
if (mCorrectionMode == Suggest.CORRECTION_FULL) {
mCorrectionMode = Suggest.CORRECTION_BASIC;
}
}
// If the dictionary is not big enough, don't auto correct
mHasDictionary = mSuggest.hasMainDictionary();
updateCorrectionMode();
mInputView.setProximityCorrectionEnabled(true);
if (mSuggest != null) {
mSuggest.setCorrectionMode(mCorrectionMode);
}
mPredictionOn = mPredictionOn && mCorrectionMode > 0;
checkTutorial(attribute.privateImeOptions);
if (TRACE) Debug.startMethodTracing("/data/trace/latinime");
@ -1150,6 +1147,18 @@ public class LatinIME extends InputMethodService
mUserDictionary.addWord(word, frequency);
}
private void updateCorrectionMode() {
mHasDictionary = mSuggest != null ? mSuggest.hasMainDictionary() : false;
mAutoCorrectOn = (mAutoCorrectEnabled || mQuickFixes)
&& !mInputTypeNoAutoCorrect && mHasDictionary;
mCorrectionMode = mAutoCorrectOn
? Suggest.CORRECTION_FULL
: (mQuickFixes ? Suggest.CORRECTION_BASIC : Suggest.CORRECTION_NONE);
if (mSuggest != null) {
mSuggest.setCorrectionMode(mCorrectionMode);
}
}
private void launchSettings() {
handleClose();
Intent intent = new Intent();
@ -1169,12 +1178,9 @@ public class LatinIME extends InputMethodService
// will continue to work
if (AutoText.getSize(mInputView) < 1) mQuickFixes = true;
mShowSuggestions = sp.getBoolean(PREF_SHOW_SUGGESTIONS, true) & mQuickFixes;
boolean autoComplete = sp.getBoolean(PREF_AUTO_COMPLETE,
mAutoCorrectEnabled = sp.getBoolean(PREF_AUTO_COMPLETE,
mResources.getBoolean(R.bool.enable_autocorrect)) & mShowSuggestions;
mAutoCorrectOn = mSuggest != null && (autoComplete || mQuickFixes);
mCorrectionMode = autoComplete
? Suggest.CORRECTION_FULL
: (mQuickFixes ? Suggest.CORRECTION_BASIC : Suggest.CORRECTION_NONE);
updateCorrectionMode();
String languageList = sp.getString(PREF_SELECTED_LANGUAGES, null);
updateSelectedLanguages(languageList);
}
@ -1274,6 +1280,7 @@ public class LatinIME extends InputMethodService
private static final int CPS_BUFFER_SIZE = 16;
private long[] mCpsIntervals = new long[CPS_BUFFER_SIZE];
private int mCpsIndex;
private boolean mInputTypeNoAutoCorrect;
private void measureCps() {
if (!LatinIME.PERF_DEBUG) return;

View File

@ -37,7 +37,9 @@ public class Suggest implements Dictionary.WordCallback {
public static final int CORRECTION_BASIC = 1;
public static final int CORRECTION_FULL = 2;
private Dictionary mMainDict;
private static final int LARGE_DICTIONARY_THRESHOLD = 200 * 1000;
private BinaryDictionary mMainDict;
private Dictionary mUserDictionary;
@ -49,9 +51,7 @@ public class Suggest implements Dictionary.WordCallback {
private int[] mPriorities = new int[mPrefMaxSuggestions];
private ArrayList<CharSequence> mSuggestions = new ArrayList<CharSequence>();
private boolean mIncludeTypedWordIfValid;
private ArrayList<CharSequence> mStringPool = new ArrayList<CharSequence>();
private Context mContext;
private boolean mHaveCorrection;
private CharSequence mOriginalWord;
private String mLowerOriginalWord;
@ -60,7 +60,6 @@ public class Suggest implements Dictionary.WordCallback {
public Suggest(Context context, int dictionaryResId) {
mContext = context;
mMainDict = new BinaryDictionary(context, dictionaryResId);
for (int i = 0; i < mPrefMaxSuggestions; i++) {
StringBuilder sb = new StringBuilder(32);
@ -76,6 +75,10 @@ public class Suggest implements Dictionary.WordCallback {
mCorrectionMode = mode;
}
public boolean hasMainDictionary() {
return mMainDict.getSize() > LARGE_DICTIONARY_THRESHOLD;
}
/**
* Sets an optional user dictionary resource to be loaded. The user dictionary is consulted
* before the main dictionary, if set.
@ -155,7 +158,6 @@ public class Suggest implements Dictionary.WordCallback {
mHaveCorrection = false;
collectGarbage();
Arrays.fill(mPriorities, 0);
mIncludeTypedWordIfValid = includeTypedWordIfValid;
// Save a lowercase version of the original word
mOriginalWord = wordComposer.getTypedWord();