aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod/latin/LatinIME.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com/android/inputmethod/latin/LatinIME.java')
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java691
1 files changed, 338 insertions, 353 deletions
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index acbccf6e6..ae2315437 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -16,16 +16,21 @@
package com.android.inputmethod.latin;
-import com.android.inputmethod.compat.InputMethodSubtype;
+import com.android.inputmethod.compat.CompatUtils;
+import com.android.inputmethod.compat.EditorInfoCompatUtils;
+import com.android.inputmethod.compat.InputConnectionCompatUtils;
+import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
+import com.android.inputmethod.compat.InputMethodServiceCompatWrapper;
+import com.android.inputmethod.compat.InputTypeCompatUtils;
+import com.android.inputmethod.compat.VibratorCompatWrapper;
+import com.android.inputmethod.deprecated.VoiceProxy;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.KeyboardActionListener;
-import com.android.inputmethod.keyboard.KeyboardId;
import com.android.inputmethod.keyboard.KeyboardSwitcher;
import com.android.inputmethod.keyboard.KeyboardView;
import com.android.inputmethod.keyboard.LatinKeyboard;
import com.android.inputmethod.keyboard.LatinKeyboardView;
import com.android.inputmethod.latin.Utils.RingCharBuffer;
-import com.android.inputmethod.voice.VoiceIMEConnector;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
@@ -41,9 +46,9 @@ import android.media.AudioManager;
import android.net.ConnectivityManager;
import android.os.Debug;
import android.os.Handler;
+import android.os.IBinder;
import android.os.Message;
import android.os.SystemClock;
-import android.os.Vibrator;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;
import android.text.InputType;
@@ -62,13 +67,10 @@ import android.view.ViewParent;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.CompletionInfo;
-// @@@ import android.view.inputmethod.CorrectionInfo;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
-import android.view.inputmethod.InputMethodManager;
-// @@@ import android.view.inputmethod.InputMethodSubtype;
import android.widget.FrameLayout;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
@@ -82,13 +84,35 @@ import java.util.Locale;
/**
* Input method implementation for Qwerty'ish keyboard.
*/
-public class LatinIME extends InputMethodService implements KeyboardActionListener,
- SharedPreferences.OnSharedPreferenceChangeListener {
- private static final String TAG = "LatinIME";
+public class LatinIME extends InputMethodServiceCompatWrapper implements KeyboardActionListener {
+ private static final String TAG = LatinIME.class.getSimpleName();
private static final boolean PERF_DEBUG = false;
private static final boolean TRACE = false;
private static boolean DEBUG = LatinImeLogger.sDBG;
+ /**
+ * The private IME option used to indicate that no microphone should be
+ * shown for a given text field. For instance, this is specified by the
+ * search dialog when the dialog is already showing a voice search button.
+ *
+ * @deprecated Use {@link LatinIME#IME_OPTION_NO_MICROPHONE} with package name prefixed.
+ */
+ @SuppressWarnings("dep-ann")
+ public static final String IME_OPTION_NO_MICROPHONE_COMPAT = "nm";
+
+ /**
+ * The private IME option used to indicate that no microphone should be
+ * shown for a given text field. For instance, this is specified by the
+ * search dialog when the dialog is already showing a voice search button.
+ */
+ public static final String IME_OPTION_NO_MICROPHONE = "noMicrophoneKey";
+
+ /**
+ * The private IME option used to indicate that no settings key should be
+ * shown for a given text field.
+ */
+ public static final String IME_OPTION_NO_SETTINGS_KEY = "noSettingsKey";
+
private static final int DELAY_UPDATE_SUGGESTIONS = 180;
private static final int DELAY_UPDATE_OLD_SUGGESTIONS = 300;
private static final int DELAY_UPDATE_SHIFT_STATE = 300;
@@ -99,6 +123,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// Key events coming any faster than this are long-presses.
private static final int QUICK_PRESS = 200;
+ /**
+ * The name of the scheme used by the Package Manager to warn of a new package installation,
+ * replacement or removal.
+ */
+ private static final String SCHEME_PACKAGE = "package";
+
private int mSuggestionVisibility;
private static final int SUGGESTION_VISIBILILTY_SHOW_VALUE
= R.string.prefs_suggestion_visibility_show_value;
@@ -120,13 +150,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private AlertDialog mOptionsDialog;
- private InputMethodManager mImm;
+ private InputMethodManagerCompatWrapper mImm;
private Resources mResources;
private SharedPreferences mPrefs;
private String mInputMethodId;
private KeyboardSwitcher mKeyboardSwitcher;
private SubtypeSwitcher mSubtypeSwitcher;
- private VoiceIMEConnector mVoiceConnector;
+ private VoiceProxy mVoiceProxy;
private UserDictionary mUserDictionary;
private UserBigramDictionary mUserBigramDictionary;
@@ -139,6 +169,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private boolean mIsSettingsSuggestionStripOn;
private boolean mApplicationSpecifiedCompletionOn;
+ private AccessibilityUtils mAccessibilityUtils;
+
private final StringBuilder mComposing = new StringBuilder();
private WordComposer mWord = new WordComposer();
private CharSequence mBestWord;
@@ -146,7 +178,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private boolean mHasDictionary;
private boolean mJustAddedAutoSpace;
private boolean mAutoCorrectEnabled;
- private boolean mReCorrectionEnabled;
+ private boolean mRecorrectionEnabled;
private boolean mBigramSuggestionEnabled;
private boolean mAutoCorrectOn;
private boolean mVibrateOn;
@@ -159,6 +191,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private int mConfigDelayBeforeFadeoutLanguageOnSpacebar;
private int mConfigDurationOfFadeoutLanguageOnSpacebar;
private float mConfigFinalFadeoutFactorOfLanguageOnSpacebar;
+ private long mConfigDoubleSpacesTurnIntoPeriodTimeout;
private int mCorrectionMode;
private int mCommittedLength;
@@ -170,7 +203,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// Indicates whether the suggestion strip is to be on in landscape
private boolean mJustAccepted;
- private boolean mJustReverted;
private int mDeleteCount;
private long mLastKeyTime;
@@ -182,60 +214,47 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
/* package */ String mWordSeparators;
private String mSentenceSeparators;
private String mSuggestPuncs;
- // TODO: Move this flag to VoiceIMEConnector
+ // TODO: Move this flag to VoiceProxy
private boolean mConfigurationChanging;
+ // Object for reacting to adding/removing a dictionary pack.
+ private BroadcastReceiver mDictionaryPackInstallReceiver =
+ new DictionaryPackInstallBroadcastReceiver(this);
+
// Keeps track of most recently inserted text (multi-character key) for reverting
private CharSequence mEnteredText;
- private boolean mRefreshKeyboardRequired;
private final ArrayList<WordAlternatives> mWordHistory = new ArrayList<WordAlternatives>();
- public abstract static class WordAlternatives {
- protected CharSequence mChosenWord;
+ public class WordAlternatives {
+ private final CharSequence mChosenWord;
+ private final WordComposer mWordComposer;
- public WordAlternatives() {
- // Nothing
- }
-
- public WordAlternatives(CharSequence chosenWord) {
+ public WordAlternatives(CharSequence chosenWord, WordComposer wordComposer) {
mChosenWord = chosenWord;
+ mWordComposer = wordComposer;
}
- @Override
- public int hashCode() {
- return mChosenWord.hashCode();
- }
-
- public abstract CharSequence getOriginalWord();
-
public CharSequence getChosenWord() {
return mChosenWord;
}
- public abstract SuggestedWords.Builder getAlternatives();
- }
-
- public class TypedWordAlternatives extends WordAlternatives {
- private WordComposer word;
-
- public TypedWordAlternatives() {
- // Nothing
+ public CharSequence getOriginalWord() {
+ return mWordComposer.getTypedWord();
}
- public TypedWordAlternatives(CharSequence chosenWord, WordComposer wordComposer) {
- super(chosenWord);
- word = wordComposer;
+ public SuggestedWords.Builder getAlternatives() {
+ return getTypedSuggestions(mWordComposer);
}
@Override
- public CharSequence getOriginalWord() {
- return word.getTypedWord();
+ public int hashCode() {
+ return mChosenWord.hashCode();
}
@Override
- public SuggestedWords.Builder getAlternatives() {
- return getTypedSuggestions(word);
+ public boolean equals(Object o) {
+ return o instanceof CharSequence && TextUtils.equals(mChosenWord, (CharSequence)o);
}
}
@@ -248,6 +267,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private static final int MSG_VOICE_RESULTS = 3;
private static final int MSG_FADEOUT_LANGUAGE_ON_SPACEBAR = 4;
private static final int MSG_DISMISS_LANGUAGE_ON_SPACEBAR = 5;
+ private static final int MSG_SPACE_TYPED = 6;
@Override
public void handleMessage(Message msg) {
@@ -264,7 +284,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
switcher.updateShiftState();
break;
case MSG_VOICE_RESULTS:
- mVoiceConnector.handleVoiceResults(preferCapitalization()
+ mVoiceProxy.handleVoiceResults(preferCapitalization()
|| (switcher.isAlphabetMode() && switcher.isShiftedOrShiftLocked()));
break;
case MSG_FADEOUT_LANGUAGE_ON_SPACEBAR:
@@ -324,7 +344,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
removeMessages(MSG_DISMISS_LANGUAGE_ON_SPACEBAR);
final LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
if (inputView != null) {
- final LatinKeyboard keyboard = inputView.getLatinKeyboard();
+ final LatinKeyboard keyboard = mKeyboardSwitcher.getLatinKeyboard();
// The language is never displayed when the delay is zero.
if (mConfigDelayBeforeFadeoutLanguageOnSpacebar != 0)
inputView.setSpacebarTextFadeFactor(localeChanged ? 1.0f
@@ -336,6 +356,20 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
}
}
+
+ public void startDoubleSpacesTimer() {
+ removeMessages(MSG_SPACE_TYPED);
+ sendMessageDelayed(obtainMessage(MSG_SPACE_TYPED),
+ mConfigDoubleSpacesTurnIntoPeriodTimeout);
+ }
+
+ public void cancelDoubleSpacesTimer() {
+ removeMessages(MSG_SPACE_TYPED);
+ }
+
+ public boolean isAcceptingDoubleSpaces() {
+ return hasMessages(MSG_SPACE_TYPED);
+ }
}
@Override
@@ -345,13 +379,15 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
LatinImeLogger.init(this, prefs);
SubtypeSwitcher.init(this, prefs);
KeyboardSwitcher.init(this, prefs);
+ AccessibilityUtils.init(this, prefs);
super.onCreate();
- mImm = ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE));
- mInputMethodId = Utils.getInputMethodId(mImm, getApplicationInfo().packageName);
+ mImm = InputMethodManagerCompatWrapper.getInstance(this);
+ mInputMethodId = Utils.getInputMethodId(mImm, getPackageName());
mSubtypeSwitcher = SubtypeSwitcher.getInstance();
mKeyboardSwitcher = KeyboardSwitcher.getInstance();
+ mAccessibilityUtils = AccessibilityUtils.getInstance();
final Resources res = getResources();
mResources = res;
@@ -359,10 +395,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// If the option should not be shown, do not read the recorrection preference
// but always use the default setting defined in the resources.
if (res.getBoolean(R.bool.config_enable_show_recorrection_option)) {
- mReCorrectionEnabled = prefs.getBoolean(Settings.PREF_RECORRECTION_ENABLED,
+ mRecorrectionEnabled = prefs.getBoolean(Settings.PREF_RECORRECTION_ENABLED,
res.getBoolean(R.bool.config_default_recorrection_enabled));
} else {
- mReCorrectionEnabled = res.getBoolean(R.bool.config_default_recorrection_enabled);
+ mRecorrectionEnabled = res.getBoolean(R.bool.config_default_recorrection_enabled);
}
mConfigEnableShowSubtypeSettings = res.getBoolean(
@@ -375,6 +411,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
R.integer.config_duration_of_fadeout_language_on_spacebar);
mConfigFinalFadeoutFactorOfLanguageOnSpacebar = res.getInteger(
R.integer.config_final_fadeout_percentage_of_language_on_spacebar) / 100.0f;
+ mConfigDoubleSpacesTurnIntoPeriodTimeout = res.getInteger(
+ R.integer.config_double_spaces_turn_into_period_timeout);
Utils.GCUtils.getInstance().reset();
boolean tryGC = true;
@@ -390,30 +428,26 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mOrientation = res.getConfiguration().orientation;
initSuggestPuncList();
- // register to receive ringer mode change and network state change.
+ // Register to receive ringer mode change and network state change.
+ // Also receive installation and removal of a dictionary pack.
final IntentFilter filter = new IntentFilter();
filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(mReceiver, filter);
- mVoiceConnector = VoiceIMEConnector.init(this, prefs, mHandler);
- prefs.registerOnSharedPreferenceChangeListener(this);
- }
+ mVoiceProxy = VoiceProxy.init(this, prefs, mHandler);
- /**
- * Returns a main dictionary resource id
- * @return main dictionary resource id
- */
- public static int getMainDictionaryResourceId(Resources res) {
- final String MAIN_DIC_NAME = "main";
- String packageName = LatinIME.class.getPackage().getName();
- return res.getIdentifier(MAIN_DIC_NAME, "raw", packageName);
+ final IntentFilter packageFilter = new IntentFilter();
+ packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
+ packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+ packageFilter.addDataScheme(SCHEME_PACKAGE);
+ registerReceiver(mDictionaryPackInstallReceiver, packageFilter);
}
private void initSuggest() {
- updateAutoTextEnabled();
- String locale = mSubtypeSwitcher.getInputLocaleStr();
+ final String localeStr = mSubtypeSwitcher.getInputLocaleStr();
+ final Locale keyboardLocale = new Locale(localeStr);
- Locale savedLocale = mSubtypeSwitcher.changeSystemLocale(new Locale(locale));
+ final Locale savedLocale = mSubtypeSwitcher.changeSystemLocale(keyboardLocale);
if (mSuggest != null) {
mSuggest.close();
}
@@ -421,20 +455,21 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mQuickFixes = isQuickFixesEnabled(prefs);
final Resources res = mResources;
- int mainDicResId = getMainDictionaryResourceId(res);
- mSuggest = new Suggest(this, mainDicResId);
+ int mainDicResId = Utils.getMainDictionaryResourceId(res);
+ mSuggest = new Suggest(this, mainDicResId, keyboardLocale);
loadAndSetAutoCorrectionThreshold(prefs);
+ updateAutoTextEnabled();
- mUserDictionary = new UserDictionary(this, locale);
+ mUserDictionary = new UserDictionary(this, localeStr);
mSuggest.setUserDictionary(mUserDictionary);
mContactsDictionary = new ContactsDictionary(this, Suggest.DIC_CONTACTS);
mSuggest.setContactsDictionary(mContactsDictionary);
- mAutoDictionary = new AutoDictionary(this, this, locale, Suggest.DIC_AUTO);
+ mAutoDictionary = new AutoDictionary(this, this, localeStr, Suggest.DIC_AUTO);
mSuggest.setAutoDictionary(mAutoDictionary);
- mUserBigramDictionary = new UserBigramDictionary(this, this, locale, Suggest.DIC_USER);
+ mUserBigramDictionary = new UserBigramDictionary(this, this, localeStr, Suggest.DIC_USER);
mSuggest.setUserBigramDictionary(mUserBigramDictionary);
updateCorrectionMode();
@@ -444,6 +479,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mSubtypeSwitcher.changeSystemLocale(savedLocale);
}
+ /* package private */ void resetSuggestMainDict() {
+ final String localeStr = mSubtypeSwitcher.getInputLocaleStr();
+ final Locale keyboardLocale = new Locale(localeStr);
+ int mainDicResId = Utils.getMainDictionaryResourceId(mResources);
+ mSuggest.resetMainDict(this, mainDicResId, keyboardLocale);
+ }
+
@Override
public void onDestroy() {
if (mSuggest != null) {
@@ -451,7 +493,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mSuggest = null;
}
unregisterReceiver(mReceiver);
- mVoiceConnector.destroy();
+ unregisterReceiver(mDictionaryPackInstallReceiver);
+ mVoiceProxy.destroy();
LatinImeLogger.commit();
LatinImeLogger.onDestroy();
super.onDestroy();
@@ -472,7 +515,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mConfigurationChanging = true;
super.onConfigurationChanged(conf);
- mVoiceConnector.onConfigurationChanged(conf);
+ mVoiceProxy.onConfigurationChanged(conf);
mConfigurationChanging = false;
}
@@ -489,7 +532,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (container.getPaddingRight() != 0) {
HorizontalScrollView scrollView =
(HorizontalScrollView) container.findViewById(R.id.candidates_scroll_view);
- // @@@ scrollView.setOverScrollMode(View.OVER_SCROLL_NEVER);
+ setOverScrollModeNever(scrollView);
container.setGravity(Gravity.CENTER_HORIZONTAL);
}
mCandidateView = (CandidateView) container.findViewById(R.id.candidates);
@@ -498,17 +541,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return container;
}
- private static boolean isPasswordVariation(int variation) {
- return variation == InputType.TYPE_TEXT_VARIATION_PASSWORD
- || variation == InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD;
- // @@@ || variation == InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD;
- }
-
- private static boolean isEmailVariation(int variation) {
- return variation == InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
- // @@@ || variation == InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS;
- }
-
@Override
public void onStartInputView(EditorInfo attribute, boolean restarting) {
final KeyboardSwitcher switcher = mKeyboardSwitcher;
@@ -524,20 +556,16 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mSubtypeSwitcher.updateParametersOnStartInputView();
- if (mRefreshKeyboardRequired) {
- mRefreshKeyboardRequired = false;
- onRefreshKeyboard();
- }
-
- TextEntryState.newSession(this);
+ TextEntryState.reset();
// Most such things we decide below in initializeInputAttributesAndGetMode, but we need to
// know now whether this is a password text field, because we need to know now whether we
// want to enable the voice button.
- mVoiceConnector.resetVoiceStates(isPasswordVariation(
- attribute.inputType & InputType.TYPE_MASK_VARIATION));
+ final VoiceProxy voiceIme = mVoiceProxy;
+ voiceIme.resetVoiceStates(InputTypeCompatUtils.isPasswordInputType(attribute.inputType)
+ || InputTypeCompatUtils.isVisiblePasswordInputType(attribute.inputType));
- final int mode = initializeInputAttributesAndGetMode(attribute.inputType);
+ initializeInputAttributes(attribute);
inputView.closing();
mEnteredText = null;
@@ -548,9 +576,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
loadSettings(attribute);
if (mSubtypeSwitcher.isKeyboardMode()) {
- switcher.loadKeyboard(mode, attribute.imeOptions,
- mVoiceConnector.isVoiceButtonEnabled(),
- mVoiceConnector.isVoiceButtonOnPrimary());
+ switcher.loadKeyboard(attribute,
+ mSubtypeSwitcher.isShortcutImeEnabled() && voiceIme.isVoiceButtonEnabled(),
+ voiceIme.isVoiceButtonOnPrimary());
switcher.updateShiftState();
}
@@ -561,18 +589,24 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
updateCorrectionMode();
+ final boolean accessibilityEnabled = mAccessibilityUtils.isAccessibilityEnabled();
+
inputView.setPreviewEnabled(mPopupOn);
inputView.setProximityCorrectionEnabled(true);
+ inputView.setAccessibilityEnabled(accessibilityEnabled);
// If we just entered a text field, maybe it has some old text that requires correction
- checkReCorrectionOnStart();
+ checkRecorrectionOnStart();
inputView.setForeground(true);
- mVoiceConnector.onStartInputView(inputView.getWindowToken());
+ voiceIme.onStartInputView(inputView.getWindowToken());
if (TRACE) Debug.startMethodTracing("/data/trace/latinime");
}
- private int initializeInputAttributesAndGetMode(int inputType) {
+ private void initializeInputAttributes(EditorInfo attribute) {
+ if (attribute == null)
+ return;
+ final int inputType = attribute.inputType;
final int variation = inputType & InputType.TYPE_MASK_VARIATION;
mAutoSpace = false;
mInputTypeNoAutoCorrect = false;
@@ -580,73 +614,52 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mApplicationSpecifiedCompletionOn = false;
mApplicationSpecifiedCompletions = null;
- final int mode;
- switch (inputType & InputType.TYPE_MASK_CLASS) {
- case InputType.TYPE_CLASS_NUMBER:
- case InputType.TYPE_CLASS_DATETIME:
- mode = KeyboardId.MODE_NUMBER;
- break;
- case InputType.TYPE_CLASS_PHONE:
- mode = KeyboardId.MODE_PHONE;
- break;
- case InputType.TYPE_CLASS_TEXT:
- mIsSettingsSuggestionStripOn = true;
- // Make sure that passwords are not displayed in candidate view
- if (isPasswordVariation(variation)) {
- mIsSettingsSuggestionStripOn = false;
- }
- if (isEmailVariation(variation)
- || variation == InputType.TYPE_TEXT_VARIATION_PERSON_NAME) {
- mAutoSpace = false;
- } else {
- mAutoSpace = true;
- }
- if (isEmailVariation(variation)) {
- mIsSettingsSuggestionStripOn = false;
- mode = KeyboardId.MODE_EMAIL;
- } else if (variation == InputType.TYPE_TEXT_VARIATION_URI) {
- mIsSettingsSuggestionStripOn = false;
- mode = KeyboardId.MODE_URL;
- } else if (variation == InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE) {
- mode = KeyboardId.MODE_IM;
- } else if (variation == InputType.TYPE_TEXT_VARIATION_FILTER) {
- mIsSettingsSuggestionStripOn = false;
- mode = KeyboardId.MODE_TEXT;
- } else if (variation == InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT) {
- mode = KeyboardId.MODE_WEB;
- // If it's a browser edit field and auto correct is not ON explicitly, then
- // disable auto correction, but keep suggestions on.
- if ((inputType & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0) {
- mInputTypeNoAutoCorrect = true;
- }
- } else {
- mode = KeyboardId.MODE_TEXT;
- }
-
- // If NO_SUGGESTIONS is set, don't do prediction.
- if ((inputType & InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS) != 0) {
- mIsSettingsSuggestionStripOn = false;
- mInputTypeNoAutoCorrect = true;
- }
- // If it's not multiline and the autoCorrect flag is not set, then don't correct
- if ((inputType & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0 &&
- (inputType & InputType.TYPE_TEXT_FLAG_MULTI_LINE) == 0) {
+ if ((inputType & InputType.TYPE_MASK_CLASS) == InputType.TYPE_CLASS_TEXT) {
+ mIsSettingsSuggestionStripOn = true;
+ // Make sure that passwords are not displayed in candidate view
+ if (InputTypeCompatUtils.isPasswordInputType(inputType)
+ || InputTypeCompatUtils.isVisiblePasswordInputType(inputType)) {
+ mIsSettingsSuggestionStripOn = false;
+ }
+ if (InputTypeCompatUtils.isEmailVariation(variation)
+ || variation == InputType.TYPE_TEXT_VARIATION_PERSON_NAME) {
+ mAutoSpace = false;
+ } else {
+ mAutoSpace = true;
+ }
+ if (InputTypeCompatUtils.isEmailVariation(variation)) {
+ mIsSettingsSuggestionStripOn = false;
+ } else if (variation == InputType.TYPE_TEXT_VARIATION_URI) {
+ mIsSettingsSuggestionStripOn = false;
+ } else if (variation == InputType.TYPE_TEXT_VARIATION_FILTER) {
+ mIsSettingsSuggestionStripOn = false;
+ } else if (variation == InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT) {
+ // If it's a browser edit field and auto correct is not ON explicitly, then
+ // disable auto correction, but keep suggestions on.
+ if ((inputType & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0) {
mInputTypeNoAutoCorrect = true;
}
- if ((inputType & InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) {
- mIsSettingsSuggestionStripOn = false;
- mApplicationSpecifiedCompletionOn = isFullscreenMode();
- }
- break;
- default:
- mode = KeyboardId.MODE_TEXT;
- break;
+ }
+
+ // If NO_SUGGESTIONS is set, don't do prediction.
+ if ((inputType & InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS) != 0) {
+ mIsSettingsSuggestionStripOn = false;
+ mInputTypeNoAutoCorrect = true;
+ }
+ // If it's not multiline and the autoCorrect flag is not set, then don't correct
+ if ((inputType & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0
+ && (inputType & InputType.TYPE_TEXT_FLAG_MULTI_LINE) == 0) {
+ mInputTypeNoAutoCorrect = true;
+ }
+ if ((inputType & InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) {
+ mIsSettingsSuggestionStripOn = false;
+ mApplicationSpecifiedCompletionOn = isFullscreenMode();
+ }
}
- return mode;
}
- private void checkReCorrectionOnStart() {
- if (!mReCorrectionEnabled) return;
+ private void checkRecorrectionOnStart() {
+ if (!mRecorrectionEnabled) return;
final InputConnection ic = getCurrentInputConnection();
if (ic == null) return;
@@ -680,7 +693,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
LatinImeLogger.commit();
mKeyboardSwitcher.onAutoCorrectionStateChanged(false);
- mVoiceConnector.flushVoiceInputLogs(mConfigurationChanging);
+ mVoiceProxy.flushVoiceInputLogs(mConfigurationChanging);
KeyboardView inputView = mKeyboardSwitcher.getInputView();
if (inputView != null) inputView.closing();
@@ -701,7 +714,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@Override
public void onUpdateExtractedText(int token, ExtractedText text) {
super.onUpdateExtractedText(token, text);
- mVoiceConnector.showPunctuationHintIfNecessary();
+ mVoiceProxy.showPunctuationHintIfNecessary();
}
@Override
@@ -714,19 +727,30 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (DEBUG) {
Log.i(TAG, "onUpdateSelection: oss=" + oldSelStart
+ ", ose=" + oldSelEnd
+ + ", lss=" + mLastSelectionStart
+ + ", lse=" + mLastSelectionEnd
+ ", nss=" + newSelStart
+ ", nse=" + newSelEnd
+ ", cs=" + candidatesStart
+ ", ce=" + candidatesEnd);
}
- mVoiceConnector.setCursorAndSelection(newSelEnd, newSelStart);
+ mVoiceProxy.setCursorAndSelection(newSelEnd, newSelStart);
// If the current selection in the text view changes, we should
// clear whatever candidate text we have.
- if ((((mComposing.length() > 0 && mHasValidSuggestions)
- || mVoiceConnector.isVoiceInputHighlighted()) && (newSelStart != candidatesEnd
- || newSelEnd != candidatesEnd) && mLastSelectionStart != newSelStart)) {
+ final boolean selectionChanged = (newSelStart != candidatesEnd
+ || newSelEnd != candidatesEnd) && mLastSelectionStart != newSelStart;
+ final boolean candidatesCleared = candidatesStart == -1 && candidatesEnd == -1;
+ if (((mComposing.length() > 0 && mHasValidSuggestions)
+ || mVoiceProxy.isVoiceInputHighlighted())
+ && (selectionChanged || candidatesCleared)) {
+ if (candidatesCleared) {
+ // If the composing span has been cleared, save the typed word in the history for
+ // recorrection before we reset the candidate strip. Then, we'll be able to show
+ // suggestions for recorrection right away.
+ saveWordInHistory(mComposing);
+ }
mComposing.setLength(0);
mHasValidSuggestions = false;
mHandler.postUpdateSuggestions();
@@ -735,17 +759,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (ic != null) {
ic.finishComposingText();
}
- mVoiceConnector.setVoiceInputHighlighted(false);
+ mVoiceProxy.setVoiceInputHighlighted(false);
} else if (!mHasValidSuggestions && !mJustAccepted) {
- switch (TextEntryState.getState()) {
- case ACCEPTED_DEFAULT:
- TextEntryState.reset();
- // $FALL-THROUGH$
- case SPACE_AFTER_PICKED:
+ if (TextEntryState.isAcceptedDefault() || TextEntryState.isSpaceAfterPicked()) {
+ if (TextEntryState.isAcceptedDefault())
+ TextEntryState.reset();
mJustAddedAutoSpace = false; // The user moved the cursor.
- break;
- default:
- break;
}
}
mJustAccepted = false;
@@ -755,18 +774,18 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mLastSelectionStart = newSelStart;
mLastSelectionEnd = newSelEnd;
- if (mReCorrectionEnabled && isShowingSuggestionsStrip()) {
+ if (mRecorrectionEnabled && isShowingSuggestionsStrip()) {
// Don't look for corrections if the keyboard is not visible
if (mKeyboardSwitcher.isInputViewShown()) {
// Check if we should go in or out of correction mode.
- if (isSuggestionsRequested() && !mJustReverted
+ if (isSuggestionsRequested()
&& (candidatesStart == candidatesEnd || newSelStart != oldSelStart
- || TextEntryState.isCorrecting())
+ || TextEntryState.isRecorrecting())
&& (newSelStart < newSelEnd - 1 || !mHasValidSuggestions)) {
if (isCursorTouchingWord() || mLastSelectionStart < mLastSelectionEnd) {
mHandler.postUpdateOldSuggestions();
} else {
- abortCorrection(false);
+ abortRecorrection(false);
// Show the punctuation suggestions list if the current one is not
// and if not showing "Touch again to save".
if (mCandidateView != null && !isShowingPunctuationList()
@@ -789,7 +808,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
*/
@Override
public void onExtractedTextClicked() {
- if (mReCorrectionEnabled && isSuggestionsRequested()) return;
+ if (mRecorrectionEnabled && isSuggestionsRequested()) return;
super.onExtractedTextClicked();
}
@@ -805,7 +824,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
*/
@Override
public void onExtractedCursorMovement(int dx, int dy) {
- if (mReCorrectionEnabled && isSuggestionsRequested()) return;
+ if (mRecorrectionEnabled && isSuggestionsRequested()) return;
super.onExtractedCursorMovement(dx, dy);
}
@@ -820,20 +839,19 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mOptionsDialog.dismiss();
mOptionsDialog = null;
}
- mVoiceConnector.hideVoiceWindow(mConfigurationChanging);
+ mVoiceProxy.hideVoiceWindow(mConfigurationChanging);
mWordHistory.clear();
super.hideWindow();
- TextEntryState.endSession();
}
@Override
public void onDisplayCompletions(CompletionInfo[] applicationSpecifiedCompletions) {
if (DEBUG) {
Log.i(TAG, "Received completions:");
- final int count = (applicationSpecifiedCompletions != null)
- ? applicationSpecifiedCompletions.length : 0;
- for (int i = 0; i < count; i++) {
- Log.i(TAG, " #" + i + ": " + applicationSpecifiedCompletions[i]);
+ if (applicationSpecifiedCompletions != null) {
+ for (int i = 0; i < applicationSpecifiedCompletions.length; i++) {
+ Log.i(TAG, " #" + i + ": " + applicationSpecifiedCompletions[i]);
+ }
}
}
if (mApplicationSpecifiedCompletionOn) {
@@ -898,8 +916,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (DEBUG) {
Log.d(TAG, "Touchable region " + x + ", " + y + ", " + width + ", " + height);
}
- //@@@outInsets.touchableInsets = InputMethodService.Insets.TOUCHABLE_INSETS_REGION;
- //@@@outInsets.touchableRegion.set(x, y, width, height);
+ setTouchableRegionCompat(outInsets, x, y, width, height);
}
}
@@ -964,7 +981,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
mCommittedLength = mComposing.length();
TextEntryState.acceptedTyped(mComposing);
- addToDictionaries(mComposing, AutoDictionary.FREQUENCY_FOR_TYPED);
+ addToAutoAndUserBigramDictionaries(mComposing, AutoDictionary.FREQUENCY_FOR_TYPED);
}
updateSuggestions();
}
@@ -1012,7 +1029,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
private void doubleSpace() {
- //if (!mAutoPunctuate) return;
if (mCorrectionMode == Suggest.CORRECTION_NONE) return;
final InputConnection ic = getCurrentInputConnection();
if (ic == null) return;
@@ -1020,13 +1036,17 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (lastThree != null && lastThree.length() == 3
&& Character.isLetterOrDigit(lastThree.charAt(0))
&& lastThree.charAt(1) == Keyboard.CODE_SPACE
- && lastThree.charAt(2) == Keyboard.CODE_SPACE) {
+ && lastThree.charAt(2) == Keyboard.CODE_SPACE
+ && mHandler.isAcceptingDoubleSpaces()) {
+ mHandler.cancelDoubleSpacesTimer();
ic.beginBatchEdit();
ic.deleteSurroundingText(2, 0);
ic.commitText(". ", 1);
ic.endBatchEdit();
mKeyboardSwitcher.updateShiftState();
mJustAddedAutoSpace = true;
+ } else {
+ mHandler.startDoubleSpacesTimer();
}
}
@@ -1106,6 +1126,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
mLastKeyTime = when;
KeyboardSwitcher switcher = mKeyboardSwitcher;
+ final boolean accessibilityEnabled = switcher.isAccessibilityEnabled();
final boolean distinctMultiTouch = switcher.hasDistinctMultitouch();
switch (primaryCode) {
case Keyboard.CODE_DELETE:
@@ -1115,12 +1136,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
break;
case Keyboard.CODE_SHIFT:
// Shift key is handled in onPress() when device has distinct multi-touch panel.
- if (!distinctMultiTouch)
+ if (!distinctMultiTouch || accessibilityEnabled)
switcher.toggleShift();
break;
case Keyboard.CODE_SWITCH_ALPHA_SYMBOL:
// Symbol key is handled in onPress() when device has distinct multi-touch panel.
- if (!distinctMultiTouch)
+ if (!distinctMultiTouch || accessibilityEnabled)
switcher.changeKeyboardMode();
break;
case Keyboard.CODE_CANCEL:
@@ -1158,10 +1179,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (isWordSeparator(primaryCode)) {
handleSeparator(primaryCode);
} else {
- handleCharacter(primaryCode, keyCodes);
+ handleCharacter(primaryCode, keyCodes, x, y);
}
- // Cancel the just reverted state
- mJustReverted = false;
}
switcher.onKey(primaryCode);
// Reset after any single keystroke
@@ -1170,10 +1189,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@Override
public void onTextInput(CharSequence text) {
- mVoiceConnector.commitVoiceInput();
+ mVoiceProxy.commitVoiceInput();
InputConnection ic = getCurrentInputConnection();
if (ic == null) return;
- abortCorrection(false);
+ abortRecorrection(false);
ic.beginBatchEdit();
commitTyped(ic);
maybeRemovePreviousPeriod(text);
@@ -1181,7 +1200,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
ic.endBatchEdit();
mKeyboardSwitcher.updateShiftState();
mKeyboardSwitcher.onKey(Keyboard.CODE_DUMMY);
- mJustReverted = false;
mJustAddedAutoSpace = false;
mEnteredText = text;
}
@@ -1193,13 +1211,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
private void handleBackspace() {
- if (mVoiceConnector.logAndRevertVoiceInput()) return;
+ if (mVoiceProxy.logAndRevertVoiceInput()) return;
final InputConnection ic = getCurrentInputConnection();
if (ic == null) return;
ic.beginBatchEdit();
- mVoiceConnector.handleBackspace();
+ mVoiceProxy.handleBackspace();
boolean deleteChar = false;
if (mHasValidSuggestions) {
@@ -1221,7 +1239,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mHandler.postUpdateShiftKeyState();
TextEntryState.backspace();
- if (TextEntryState.getState() == TextEntryState.State.UNDO_COMMIT) {
+ if (TextEntryState.isUndoCommit()) {
revertLastWord(deleteChar);
ic.endBatchEdit();
return;
@@ -1246,16 +1264,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
}
}
- mJustReverted = false;
ic.endBatchEdit();
}
private void handleTab() {
final int imeOptions = getCurrentInputEditorInfo().imeOptions;
- final int navigationFlags = 0;
- // @@@ final int navigationFlags =
- // @@@ EditorInfo.IME_FLAG_NAVIGATE_NEXT | EditorInfo.IME_FLAG_NAVIGATE_PREVIOUS;
- if ((imeOptions & navigationFlags) == 0) {
+ if (!EditorInfoCompatUtils.hasFlagNavigateNext(imeOptions)
+ && !EditorInfoCompatUtils.hasFlagNavigatePrevious(imeOptions)) {
sendDownUpKeyEvents(KeyEvent.KEYCODE_TAB);
return;
}
@@ -1264,33 +1279,32 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (ic == null)
return;
- /* @@@
// True if keyboard is in either chording shift or manual temporary upper case mode.
final boolean isManualTemporaryUpperCase = mKeyboardSwitcher.isManualTemporaryUpperCase();
- if ((imeOptions & EditorInfo.IME_FLAG_NAVIGATE_NEXT) != 0
+ if (EditorInfoCompatUtils.hasFlagNavigateNext(imeOptions)
&& !isManualTemporaryUpperCase) {
+ EditorInfoCompatUtils.performEditorActionNext(ic);
ic.performEditorAction(EditorInfo.IME_ACTION_NEXT);
- } else if ((imeOptions & EditorInfo.IME_FLAG_NAVIGATE_PREVIOUS) != 0
+ } else if (EditorInfoCompatUtils.hasFlagNavigatePrevious(imeOptions)
&& isManualTemporaryUpperCase) {
- ic.performEditorAction(EditorInfo.IME_ACTION_PREVIOUS);
+ EditorInfoCompatUtils.performEditorActionPrevious(ic);
}
- */
}
- private void abortCorrection(boolean force) {
- if (force || TextEntryState.isCorrecting()) {
- TextEntryState.onAbortCorrection();
+ private void abortRecorrection(boolean force) {
+ if (force || TextEntryState.isRecorrecting()) {
+ TextEntryState.onAbortRecorrection();
setCandidatesViewShown(isCandidateStripVisible());
getCurrentInputConnection().finishComposingText();
clearSuggestions();
}
}
- private void handleCharacter(int primaryCode, int[] keyCodes) {
- mVoiceConnector.handleCharacter();
+ private void handleCharacter(int primaryCode, int[] keyCodes, int x, int y) {
+ mVoiceProxy.handleCharacter();
- if (mLastSelectionStart == mLastSelectionEnd && TextEntryState.isCorrecting()) {
- abortCorrection(false);
+ if (mLastSelectionStart == mLastSelectionEnd && TextEntryState.isRecorrecting()) {
+ abortRecorrection(false);
}
int code = primaryCode;
@@ -1300,6 +1314,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mComposing.setLength(0);
saveWordInHistory(mBestWord);
mWord.reset();
+ clearSuggestions();
}
}
KeyboardSwitcher switcher = mKeyboardSwitcher;
@@ -1327,7 +1342,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mWord.setFirstCharCapitalized(true);
}
mComposing.append((char) code);
- mWord.add(code, keyCodes);
+ mWord.add(code, keyCodes, x, y);
InputConnection ic = getCurrentInputConnection();
if (ic != null) {
// If it's the first letter, make note of auto-caps state
@@ -1346,7 +1361,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
private void handleSeparator(int primaryCode) {
- mVoiceConnector.handleSeparator();
+ mVoiceProxy.handleSeparator();
// Should dismiss the "Touch again to save" message when handling separator
if (mCandidateView != null && mCandidateView.dismissAddToDictionaryHint()) {
@@ -1358,14 +1373,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final InputConnection ic = getCurrentInputConnection();
if (ic != null) {
ic.beginBatchEdit();
- abortCorrection(false);
+ abortRecorrection(false);
}
if (mHasValidSuggestions) {
// In certain languages where single quote is a separator, it's better
// not to auto correct, but accept the typed word. For instance,
// in Italian dov' should not be expanded to dove' because the elision
// requires the last vowel to be removed.
- if (mAutoCorrectOn && primaryCode != '\'' && !mJustReverted) {
+ if (mAutoCorrectOn && primaryCode != '\'') {
pickedDefault = pickDefaultSuggestion();
// Picked the suggestion by the space key. We consider this
// as "added an auto space".
@@ -1384,14 +1399,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// Handle the case of ". ." -> " .." with auto-space if necessary
// before changing the TextEntryState.
- if (TextEntryState.getState() == TextEntryState.State.PUNCTUATION_AFTER_ACCEPTED
- && primaryCode == Keyboard.CODE_PERIOD) {
+ if (TextEntryState.isPunctuationAfterAccepted() && primaryCode == Keyboard.CODE_PERIOD) {
reswapPeriodAndSpace();
}
TextEntryState.typedCharacter((char) primaryCode, true);
- if (TextEntryState.getState() == TextEntryState.State.PUNCTUATION_AFTER_ACCEPTED
- && primaryCode != Keyboard.CODE_ENTER) {
+ if (TextEntryState.isPunctuationAfterAccepted() && primaryCode != Keyboard.CODE_ENTER) {
swapPunctuationAndSpace();
} else if (isSuggestionsRequested() && primaryCode == Keyboard.CODE_SPACE) {
doubleSpace();
@@ -1400,13 +1413,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
CharSequence typedWord = mWord.getTypedWord();
TextEntryState.backToAcceptedDefault(typedWord);
if (!TextUtils.isEmpty(typedWord) && !typedWord.equals(mBestWord)) {
- if (ic != null) {
- /* @@@
- CorrectionInfo correctionInfo = new CorrectionInfo(
- mLastSelectionEnd - typedWord.length(), typedWord, mBestWord);
- ic.commitCorrection(correctionInfo);
- */
- }
+ InputConnectionCompatUtils.commitCorrection(
+ ic, mLastSelectionEnd - typedWord.length(), typedWord, mBestWord);
if (mCandidateView != null)
mCandidateView.onAutoCorrectionInverted(mBestWord);
}
@@ -1420,17 +1428,15 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private void handleClose() {
commitTyped(getCurrentInputConnection());
- mVoiceConnector.handleClose();
+ mVoiceProxy.handleClose();
requestHideSelf(0);
LatinKeyboardView inputView = mKeyboardSwitcher.getInputView();
if (inputView != null)
inputView.closing();
- TextEntryState.endSession();
}
private void saveWordInHistory(CharSequence result) {
if (mWord.size() <= 1) {
- mWord.reset();
return;
}
// Skip if result is null. It happens in some edge case.
@@ -1440,7 +1446,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// Make a copy of the CharSequence, since it is/could be a mutable CharSequence
final String resultCopy = result.toString();
- TypedWordAlternatives entry = new TypedWordAlternatives(resultCopy,
+ WordAlternatives entry = new WordAlternatives(resultCopy,
new WordComposer(mWord));
mWordHistory.add(entry);
}
@@ -1463,7 +1469,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private boolean isCandidateStripVisible() {
if (mCandidateView == null)
return false;
- if (mCandidateView.isShowingAddToDictionaryHint() || TextEntryState.isCorrecting())
+ if (mCandidateView.isShowingAddToDictionaryHint() || TextEntryState.isRecorrecting())
return true;
if (!isShowingSuggestionsStrip())
return false;
@@ -1473,26 +1479,21 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
public void switchToKeyboardView() {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- if (DEBUG) {
- Log.d(TAG, "Switch to keyboard view.");
- }
- View v = mKeyboardSwitcher.getInputView();
- if (v != null) {
- // Confirms that the keyboard view doesn't have parent view.
- ViewParent p = v.getParent();
- if (p != null && p instanceof ViewGroup) {
- ((ViewGroup) p).removeView(v);
- }
- setInputView(v);
- }
- setCandidatesViewShown(isCandidateStripVisible());
- updateInputViewShown();
- mHandler.postUpdateSuggestions();
+ if (DEBUG) {
+ Log.d(TAG, "Switch to keyboard view.");
+ }
+ View v = mKeyboardSwitcher.getInputView();
+ if (v != null) {
+ // Confirms that the keyboard view doesn't have parent view.
+ ViewParent p = v.getParent();
+ if (p != null && p instanceof ViewGroup) {
+ ((ViewGroup) p).removeView(v);
}
- });
+ setInputView(v);
+ }
+ setCandidatesViewShown(isCandidateStripVisible());
+ updateInputViewShown();
+ mHandler.postUpdateSuggestions();
}
public void clearSuggestions() {
@@ -1500,7 +1501,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
public void setSuggestions(SuggestedWords words) {
- if (mVoiceConnector.getAndResetIsShowingHint()) {
+ if (mVoiceProxy.getAndResetIsShowingHint()) {
setCandidatesView(mCandidateViewContainer);
}
@@ -1514,11 +1515,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
public void updateSuggestions() {
- mKeyboardSwitcher.setPreferredLetters(null);
-
// Check if we have a suggestion engine attached.
if ((mSuggest == null || !isSuggestionsRequested())
- && !mVoiceConnector.isVoiceInputHighlighted()) {
+ && !mVoiceProxy.isVoiceInputHighlighted()) {
return;
}
@@ -1534,36 +1533,30 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
private void showCorrections(WordAlternatives alternatives) {
- mKeyboardSwitcher.setPreferredLetters(null);
SuggestedWords.Builder builder = alternatives.getAlternatives();
builder.setTypedWordValid(false).setHasMinimalSuggestion(false);
showSuggestions(builder.build(), alternatives.getOriginalWord());
}
private void showSuggestions(WordComposer word) {
- // TODO Maybe need better way of retrieving previous word
+ // TODO: May need a better way of retrieving previous word
CharSequence prevWord = EditingUtils.getPreviousWord(getCurrentInputConnection(),
mWordSeparators);
SuggestedWords.Builder builder = mSuggest.getSuggestedWordBuilder(
mKeyboardSwitcher.getInputView(), word, prevWord);
- int[] nextLettersFrequencies = mSuggest.getNextLettersFrequencies();
- mKeyboardSwitcher.setPreferredLetters(nextLettersFrequencies);
-
- boolean correctionAvailable = !mInputTypeNoAutoCorrect && !mJustReverted
- && mSuggest.hasAutoCorrection();
+ boolean correctionAvailable = !mInputTypeNoAutoCorrect && mSuggest.hasAutoCorrection();
final CharSequence typedWord = word.getTypedWord();
- // If we're in basic correct
- final boolean typedWordValid = mSuggest.isValidWord(typedWord) ||
- (preferCapitalization()
- && mSuggest.isValidWord(typedWord.toString().toLowerCase()));
+ // Here, we want to promote a whitelisted word if exists.
+ final boolean typedWordValid = AutoCorrection.isValidWordForAutoCorrection(
+ mSuggest.getUnigramDictionaries(), typedWord, preferCapitalization());
if (mCorrectionMode == Suggest.CORRECTION_FULL
|| mCorrectionMode == Suggest.CORRECTION_FULL_BIGRAM) {
correctionAvailable |= typedWordValid;
}
// Don't auto-correct words with multiple capital letter
correctionAvailable &= !word.isMostlyCaps();
- correctionAvailable &= !TextEntryState.isCorrecting();
+ correctionAvailable &= !TextEntryState.isRecorrecting();
// Basically, we update the suggestion strip only when suggestion count > 1. However,
// there is an exception: We update the suggestion strip whenever typed word's length
@@ -1610,7 +1603,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mJustAccepted = true;
pickSuggestion(mBestWord);
// Add the word to the auto dictionary if it's not a known word
- addToDictionaries(mBestWord, AutoDictionary.FREQUENCY_FOR_TYPED);
+ addToAutoAndUserBigramDictionaries(mBestWord, AutoDictionary.FREQUENCY_FOR_TYPED);
return true;
}
@@ -1619,9 +1612,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
public void pickSuggestionManually(int index, CharSequence suggestion) {
SuggestedWords suggestions = mCandidateView.getSuggestions();
- mVoiceConnector.flushAndLogAllTextModificationCounters(index, suggestion, mWordSeparators);
+ mVoiceProxy.flushAndLogAllTextModificationCounters(index, suggestion, mWordSeparators);
- final boolean correcting = TextEntryState.isCorrecting();
+ final boolean recorrecting = TextEntryState.isRecorrecting();
InputConnection ic = getCurrentInputConnection();
if (ic != null) {
ic.beginBatchEdit();
@@ -1663,24 +1656,35 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
pickSuggestion(suggestion);
// Add the word to the auto dictionary if it's not a known word
if (index == 0) {
- addToDictionaries(suggestion, AutoDictionary.FREQUENCY_FOR_PICKED);
+ addToAutoAndUserBigramDictionaries(suggestion, AutoDictionary.FREQUENCY_FOR_PICKED);
} else {
- addToBigramDictionary(suggestion, 1);
+ addToOnlyBigramDictionary(suggestion, 1);
}
LatinImeLogger.logOnManualSuggestion(mComposing.toString(), suggestion.toString(),
index, suggestions.mWords);
TextEntryState.acceptedSuggestion(mComposing.toString(), suggestion);
// Follow it with a space
- if (mAutoSpace && !correcting) {
+ if (mAutoSpace && !recorrecting) {
sendSpace();
mJustAddedAutoSpace = true;
}
- final boolean showingAddToDictionaryHint = index == 0 && mCorrectionMode > 0
- && !mSuggest.isValidWord(suggestion)
- && !mSuggest.isValidWord(suggestion.toString().toLowerCase());
-
- if (!correcting) {
+ // We should show the hint if the user pressed the first entry AND either:
+ // - There is no dictionary (we know that because we tried to load it => null != mSuggest
+ // AND mHasDictionary is false)
+ // - There is a dictionary and the word is not in it
+ // Please note that if mSuggest is null, it means that everything is off: suggestion
+ // and correction, so we shouldn't try to show the hint
+ // We used to look at mCorrectionMode here, but showing the hint should have nothing
+ // to do with the autocorrection setting.
+ final boolean showingAddToDictionaryHint = index == 0 && mSuggest != null
+ // If there is no dictionary the hint should be shown.
+ && (!mHasDictionary
+ // If "suggestion" is not in the dictionary, the hint should be shown.
+ || !AutoCorrection.isValidWord(
+ mSuggest.getUnigramDictionaries(), suggestion, true));
+
+ if (!recorrecting) {
// Fool the state watcher so that a subsequent backspace will not do a revert, unless
// we just did a correction, in which case we need to stay in
// TextEntryState.State.PICKED_SUGGESTION state.
@@ -1712,13 +1716,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return;
InputConnection ic = getCurrentInputConnection();
if (ic != null) {
- mVoiceConnector.rememberReplacedWord(suggestion, mWordSeparators);
+ mVoiceProxy.rememberReplacedWord(suggestion, mWordSeparators);
ic.commitText(suggestion, 1);
}
saveWordInHistory(suggestion);
mHasValidSuggestions = false;
mCommittedLength = suggestion.length();
- switcher.setPreferredLetters(null);
}
/**
@@ -1731,31 +1734,30 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// If we didn't find a match, search for result in typed word history
WordComposer foundWord = null;
WordAlternatives alternatives = null;
+ // Search old suggestions to suggest re-corrected suggestions.
for (WordAlternatives entry : mWordHistory) {
if (TextUtils.equals(entry.getChosenWord(), touching.mWord)) {
- if (entry instanceof TypedWordAlternatives) {
- foundWord = ((TypedWordAlternatives) entry).word;
- }
+ foundWord = entry.mWordComposer;
alternatives = entry;
break;
}
}
- // If we didn't find a match, at least suggest corrections.
+ // If we didn't find a match, at least suggest corrections as re-corrected suggestions.
if (foundWord == null
- && (mSuggest.isValidWord(touching.mWord)
- || mSuggest.isValidWord(touching.mWord.toString().toLowerCase()))) {
+ && (AutoCorrection.isValidWord(
+ mSuggest.getUnigramDictionaries(), touching.mWord, true))) {
foundWord = new WordComposer();
for (int i = 0; i < touching.mWord.length(); i++) {
foundWord.add(touching.mWord.charAt(i), new int[] {
touching.mWord.charAt(i)
- });
+ }, WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE);
}
foundWord.setFirstCharCapitalized(Character.isUpperCase(touching.mWord.charAt(0)));
}
// Found a match, show suggestions
if (foundWord != null || alternatives != null) {
if (alternatives == null) {
- alternatives = new TypedWordAlternatives(touching.mWord, foundWord);
+ alternatives = new WordAlternatives(touching.mWord, foundWord);
}
showCorrections(alternatives);
if (foundWord != null) {
@@ -1769,7 +1771,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
private void setOldSuggestions() {
- mVoiceConnector.setShowingVoiceSuggestions(false);
+ mVoiceProxy.setShowingVoiceSuggestions(false);
if (mCandidateView != null && mCandidateView.isShowingAddToDictionaryHint()) {
return;
}
@@ -1783,21 +1785,21 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (touching != null && touching.mWord.length() > 1) {
ic.beginBatchEdit();
- if (!mVoiceConnector.applyVoiceAlternatives(touching)
+ if (!mVoiceProxy.applyVoiceAlternatives(touching)
&& !applyTypedAlternatives(touching)) {
- abortCorrection(true);
+ abortRecorrection(true);
} else {
- TextEntryState.selectedForCorrection();
+ TextEntryState.selectedForRecorrection();
EditingUtils.underlineWord(ic, touching);
}
ic.endBatchEdit();
} else {
- abortCorrection(true);
+ abortRecorrection(true);
setPunctuationSuggestions(); // Show the punctuation suggestions list
}
} else {
- abortCorrection(true);
+ abortRecorrection(true);
}
}
@@ -1806,21 +1808,22 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
setCandidatesViewShown(isCandidateStripVisible());
}
- private void addToDictionaries(CharSequence suggestion, int frequencyDelta) {
+ private void addToAutoAndUserBigramDictionaries(CharSequence suggestion, int frequencyDelta) {
checkAddToDictionary(suggestion, frequencyDelta, false);
}
- private void addToBigramDictionary(CharSequence suggestion, int frequencyDelta) {
+ private void addToOnlyBigramDictionary(CharSequence suggestion, int frequencyDelta) {
checkAddToDictionary(suggestion, frequencyDelta, true);
}
/**
* Adds to the UserBigramDictionary and/or AutoDictionary
- * @param addToBigramDictionary true if it should be added to bigram dictionary if possible
+ * @param selectedANotTypedWord true if it should be added to bigram dictionary if possible
*/
private void checkAddToDictionary(CharSequence suggestion, int frequencyDelta,
- boolean addToBigramDictionary) {
+ boolean selectedANotTypedWord) {
if (suggestion == null || suggestion.length() < 1) return;
+
// Only auto-add to dictionary if auto-correct is ON. Otherwise we'll be
// adding words in situations where the user or application really didn't
// want corrections enabled or learned.
@@ -1828,9 +1831,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|| mCorrectionMode == Suggest.CORRECTION_FULL_BIGRAM)) {
return;
}
- if (!addToBigramDictionary && mAutoDictionary.isValidWord(suggestion)
- || (!mSuggest.isValidWord(suggestion.toString())
- && !mSuggest.isValidWord(suggestion.toString().toLowerCase()))) {
+
+ final boolean selectedATypedWordAndItsInAutoDic =
+ !selectedANotTypedWord && mAutoDictionary.isValidWord(suggestion);
+ final boolean isValidWord = AutoCorrection.isValidWord(
+ mSuggest.getUnigramDictionaries(), suggestion, true);
+ final boolean needsToAddToAutoDictionary = selectedATypedWordAndItsInAutoDic
+ || !isValidWord;
+ if (needsToAddToAutoDictionary) {
mAutoDictionary.addWord(suggestion.toString(), frequencyDelta);
}
@@ -1870,7 +1878,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final int length = mComposing.length();
if (!mHasValidSuggestions && length > 0) {
final InputConnection ic = getCurrentInputConnection();
- mJustReverted = true;
final CharSequence punctuation = ic.getTextBeforeCursor(1, 0);
if (deleteChar) ic.deleteSurroundingText(1, 0);
int toDelete = mCommittedLength;
@@ -1898,7 +1905,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mHandler.postUpdateSuggestions();
} else {
sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
- mJustReverted = false;
}
}
@@ -1936,28 +1942,11 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mSubtypeSwitcher.toggleLanguage(reset, next);
}
// Reload keyboard because the current language has been changed.
- KeyboardSwitcher switcher = mKeyboardSwitcher;
- final EditorInfo attribute = getCurrentInputEditorInfo();
- final int mode = initializeInputAttributesAndGetMode((attribute != null)
- ? attribute.inputType : 0);
- final int imeOptions = (attribute != null) ? attribute.imeOptions : 0;
- switcher.loadKeyboard(mode, imeOptions, mVoiceConnector.isVoiceButtonEnabled(),
- mVoiceConnector.isVoiceButtonOnPrimary());
+ mKeyboardSwitcher.loadKeyboard(getCurrentInputEditorInfo(),
+ mSubtypeSwitcher.isShortcutImeEnabled() && mVoiceProxy.isVoiceButtonEnabled(),
+ mVoiceProxy.isVoiceButtonOnPrimary());
initSuggest();
- switcher.updateShiftState();
- }
-
- @Override
- public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
- String key) {
- mSubtypeSwitcher.onSharedPreferenceChanged(sharedPreferences, key);
- if (Settings.PREF_SELECTED_LANGUAGES.equals(key)) {
- mRefreshKeyboardRequired = true;
- } else if (Settings.PREF_RECORRECTION_ENABLED.equals(key)) {
- mReCorrectionEnabled = sharedPreferences.getBoolean(
- Settings.PREF_RECORRECTION_ENABLED,
- mResources.getBoolean(R.bool.config_default_recorrection_enabled));
- }
+ mKeyboardSwitcher.updateShiftState();
}
@Override
@@ -1967,7 +1956,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
@Override
- public void onPress(int primaryCode) {
+ public void onPress(int primaryCode, boolean withSliding) {
if (mKeyboardSwitcher.isVibrateAndSoundFeedbackRequired()) {
vibrate();
playKeyClick(primaryCode);
@@ -1975,25 +1964,27 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
KeyboardSwitcher switcher = mKeyboardSwitcher;
final boolean distinctMultiTouch = switcher.hasDistinctMultitouch();
if (distinctMultiTouch && primaryCode == Keyboard.CODE_SHIFT) {
- switcher.onPressShift();
+ switcher.onPressShift(withSliding);
} else if (distinctMultiTouch && primaryCode == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
switcher.onPressSymbol();
} else {
switcher.onOtherKeyPressed();
}
+ mAccessibilityUtils.onPress(primaryCode, switcher);
}
@Override
- public void onRelease(int primaryCode) {
+ public void onRelease(int primaryCode, boolean withSliding) {
KeyboardSwitcher switcher = mKeyboardSwitcher;
// Reset any drag flags in the keyboard
switcher.keyReleased();
final boolean distinctMultiTouch = switcher.hasDistinctMultitouch();
if (distinctMultiTouch && primaryCode == Keyboard.CODE_SHIFT) {
- switcher.onReleaseShift();
+ switcher.onReleaseShift(withSliding);
} else if (distinctMultiTouch && primaryCode == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
switcher.onReleaseSymbol();
}
+ mAccessibilityUtils.onRelease(primaryCode, switcher);
}
@@ -2073,6 +2064,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
private void updateCorrectionMode() {
+ // TODO: cleanup messy flags
mHasDictionary = mSuggest != null ? mSuggest.hasMainDictionary() : false;
mAutoCorrectOn = (mAutoCorrectEnabled || mQuickFixes)
&& !mInputTypeNoAutoCorrect && mHasDictionary;
@@ -2124,10 +2116,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private void loadSettings(EditorInfo attribute) {
// Get the settings preferences
final SharedPreferences prefs = mPrefs;
- Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
- // @@@ mVibrateOn = vibrator != null && vibrator.hasVibrator()
- mVibrateOn = vibrator != null
- && prefs.getBoolean(Settings.PREF_VIBRATE_ON, false);
+ final boolean hasVibrator = VibratorCompatWrapper.getInstance(this).hasVibrator();
+ mVibrateOn = hasVibrator && prefs.getBoolean(Settings.PREF_VIBRATE_ON, false);
mSoundOn = prefs.getBoolean(Settings.PREF_SOUND_ON,
mResources.getBoolean(R.bool.config_default_sound_enabled));
@@ -2139,7 +2129,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mBigramSuggestionEnabled = mAutoCorrectEnabled && isBigramSuggestionEnabled(prefs);
loadAndSetAutoCorrectionThreshold(prefs);
- mVoiceConnector.loadSettings(attribute, prefs);
+ mVoiceProxy.loadSettings(attribute, prefs);
updateCorrectionMode();
updateAutoTextEnabled();
@@ -2250,13 +2240,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
di.dismiss();
switch (position) {
case 0:
- Intent intent = new Intent(
- android.provider.Settings.ACTION_INPUT_METHOD_SUBTYPE_SETTINGS);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ Intent intent = CompatUtils.getInputLanguageSelectionIntent(
+ mInputMethodId, Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
- intent.putExtra(android.provider.Settings.EXTRA_INPUT_METHOD_ID,
- mInputMethodId);
startActivity(intent);
break;
case 1:
@@ -2293,6 +2280,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private void showOptionsMenuInternal(CharSequence title, CharSequence[] items,
DialogInterface.OnClickListener listener) {
+ final IBinder windowToken = mKeyboardSwitcher.getInputView().getWindowToken();
+ if (windowToken == null) return;
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setCancelable(true);
builder.setIcon(R.drawable.ic_dialog_keyboard);
@@ -2303,7 +2292,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mOptionsDialog.setCanceledOnTouchOutside(true);
Window window = mOptionsDialog.getWindow();
WindowManager.LayoutParams lp = window.getAttributes();
- lp.token = mKeyboardSwitcher.getInputView().getWindowToken();
+ lp.token = windowToken;
lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
window.setAttributes(lp);
window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
@@ -2347,8 +2336,4 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
for (int i = 0; i < CPS_BUFFER_SIZE; i++) total += mCpsIntervals[i];
System.out.println("CPS = " + ((CPS_BUFFER_SIZE * 1000f) / total));
}
-
- public void onCurrentInputMethodSubtypeChanged(InputMethodSubtype subtype) {
- SubtypeSwitcher.getInstance().updateSubtype(subtype);
- }
}