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.java959
1 files changed, 541 insertions, 418 deletions
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index e2a76a456..bb7e2d1c2 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1,17 +1,17 @@
/*
* Copyright (C) 2008 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
+ * 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
+ * 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.
+ * 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;
@@ -35,6 +35,7 @@ import android.graphics.Rect;
import android.inputmethodservice.InputMethodService;
import android.media.AudioManager;
import android.net.ConnectivityManager;
+import android.os.Build.VERSION_CODES;
import android.os.Debug;
import android.os.Handler;
import android.os.HandlerThread;
@@ -60,18 +61,16 @@ import android.view.inputmethod.InputMethodSubtype;
import com.android.inputmethod.accessibility.AccessibilityUtils;
import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy;
-import com.android.inputmethod.compat.CompatUtils;
-import com.android.inputmethod.compat.InputMethodManagerCompatWrapper;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.compat.InputMethodServiceCompatUtils;
import com.android.inputmethod.compat.SuggestionSpanUtils;
+import com.android.inputmethod.event.EventInterpreter;
import com.android.inputmethod.keyboard.KeyDetector;
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.MainKeyboardView;
-import com.android.inputmethod.latin.LocaleUtils.RunInLocale;
import com.android.inputmethod.latin.Utils.Stats;
import com.android.inputmethod.latin.define.ProductionFlag;
import com.android.inputmethod.latin.suggestions.SuggestionStripView;
@@ -81,6 +80,7 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Locale;
+import java.util.TreeSet;
/**
* Input method implementation for Qwerty'ish keyboard.
@@ -126,22 +126,25 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// Current space state of the input method. This can be any of the above constants.
private int mSpaceState;
- private SettingsValues mCurrentSettings;
+ private final Settings mSettings;
private View mExtractArea;
private View mKeyPreviewBackingView;
private View mSuggestionsContainer;
private SuggestionStripView mSuggestionStripView;
- /* package for tests */ Suggest mSuggest;
+ // Never null
+ private SuggestedWords mSuggestedWords = SuggestedWords.EMPTY;
+ @UsedForTesting Suggest mSuggest;
private CompletionInfo[] mApplicationSpecifiedCompletions;
private ApplicationInfo mTargetApplicationInfo;
- private InputMethodManagerCompatWrapper mImm;
- private Resources mResources;
- private SharedPreferences mPrefs;
- /* package for tests */ final KeyboardSwitcher mKeyboardSwitcher;
+ private RichInputMethodManager mRichImm;
+ @UsedForTesting final KeyboardSwitcher mKeyboardSwitcher;
private final SubtypeSwitcher mSubtypeSwitcher;
private final SubtypeState mSubtypeState = new SubtypeState();
+ // At start, create a default event interpreter that does nothing by passing it no decoder spec.
+ // The event interpreter should never be null.
+ private EventInterpreter mEventInterpreter = new EventInterpreter(this);
private boolean mIsMainDictionaryAvailable;
private UserBinaryDictionary mUserDictionary;
@@ -164,18 +167,19 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
private boolean mExpectingUpdateSelection;
private int mDeleteCount;
private long mLastKeyTime;
-
- private AudioAndHapticFeedbackManager mFeedbackManager;
+ private TreeSet<Long> mCurrentlyPressedHardwareKeys = CollectionUtils.newTreeSet();
// Member variables for remembering the current device orientation.
private int mDisplayOrientation;
// Object for reacting to adding/removing a dictionary pack.
+ // TODO: The experimental version is not supported by the Dictionary Pack Service yet.
private BroadcastReceiver mDictionaryPackInstallReceiver =
- new DictionaryPackInstallBroadcastReceiver(this);
+ ProductionFlag.IS_EXPERIMENTAL
+ ? null : new DictionaryPackInstallBroadcastReceiver(this);
// Keeps track of most recently inserted text (multi-character key) for reverting
- private CharSequence mEnteredText;
+ private String mEnteredText;
private boolean mIsAutoCorrectionIndicatorOn;
@@ -195,8 +199,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
private int mDelayUpdateSuggestions;
private int mDelayUpdateShiftState;
- private long mDoubleSpacesTurnIntoPeriodTimeout;
- private long mDoubleSpaceTimerStart;
+ private long mDoubleSpacePeriodTimeout;
+ private long mDoubleSpacePeriodTimerStart;
public UIHandler(final LatinIME outerInstance) {
super(outerInstance);
@@ -208,8 +212,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
res.getInteger(R.integer.config_delay_update_suggestions);
mDelayUpdateShiftState =
res.getInteger(R.integer.config_delay_update_shift_state);
- mDoubleSpacesTurnIntoPeriodTimeout = res.getInteger(
- R.integer.config_double_spaces_turn_into_period_timeout);
+ mDoubleSpacePeriodTimeout =
+ res.getInteger(R.integer.config_double_space_period_timeout);
}
@Override
@@ -260,17 +264,17 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
.sendToTarget();
}
- public void startDoubleSpacesTimer() {
- mDoubleSpaceTimerStart = SystemClock.uptimeMillis();
+ public void startDoubleSpacePeriodTimer() {
+ mDoubleSpacePeriodTimerStart = SystemClock.uptimeMillis();
}
- public void cancelDoubleSpacesTimer() {
- mDoubleSpaceTimerStart = 0;
+ public void cancelDoubleSpacePeriodTimer() {
+ mDoubleSpacePeriodTimerStart = 0;
}
- public boolean isAcceptingDoubleSpaces() {
- return SystemClock.uptimeMillis() - mDoubleSpaceTimerStart
- < mDoubleSpacesTurnIntoPeriodTimeout;
+ public boolean isAcceptingDoubleSpacePeriod() {
+ return SystemClock.uptimeMillis() - mDoubleSpacePeriodTimerStart
+ < mDoubleSpacePeriodTimeout;
}
// Working variables for the following methods.
@@ -375,9 +379,9 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
mCurrentSubtypeUsed = true;
}
- public void switchSubtype(final IBinder token, final InputMethodManagerCompatWrapper imm,
- final Context context) {
- final InputMethodSubtype currentSubtype = imm.getCurrentInputMethodSubtype();
+ public void switchSubtype(final IBinder token, final RichInputMethodManager richImm) {
+ final InputMethodSubtype currentSubtype = richImm.getInputMethodManager()
+ .getCurrentInputMethodSubtype();
final InputMethodSubtype lastActiveSubtype = mLastActiveSubtype;
final boolean currentSubtypeUsed = mCurrentSubtypeUsed;
if (currentSubtypeUsed) {
@@ -385,18 +389,18 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
mCurrentSubtypeUsed = false;
}
if (currentSubtypeUsed
- && ImfUtils.checkIfSubtypeBelongsToThisImeAndEnabled(context, lastActiveSubtype)
+ && richImm.checkIfSubtypeBelongsToThisImeAndEnabled(lastActiveSubtype)
&& !currentSubtype.equals(lastActiveSubtype)) {
- final String id = ImfUtils.getInputMethodIdOfThisIme(context);
- imm.setInputMethodAndSubtype(token, id, lastActiveSubtype);
+ richImm.setInputMethodAndSubtype(token, lastActiveSubtype);
return;
}
- imm.switchToNextInputMethod(token, true /* onlyCurrentIme */);
+ richImm.switchToNextInputMethod(token, true /* onlyCurrentIme */);
}
}
public LatinIME() {
super();
+ mSettings = Settings.getInstance();
mSubtypeSwitcher = SubtypeSwitcher.getInstance();
mKeyboardSwitcher = KeyboardSwitcher.getInstance();
mIsHardwareAcceleratedDrawingEnabled =
@@ -406,33 +410,27 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
@Override
public void onCreate() {
- final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
- mPrefs = prefs;
- LatinImeLogger.init(this, prefs);
- if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.getInstance().init(this, prefs);
- }
- InputMethodManagerCompatWrapper.init(this);
+ Settings.init(this);
+ LatinImeLogger.init(this);
+ RichInputMethodManager.init(this);
+ mRichImm = RichInputMethodManager.getInstance();
SubtypeSwitcher.init(this);
- KeyboardSwitcher.init(this, prefs);
+ KeyboardSwitcher.init(this);
+ AudioAndHapticFeedbackManager.init(this);
AccessibilityUtils.init(this);
super.onCreate();
- mImm = InputMethodManagerCompatWrapper.getInstance();
mHandler.onCreate();
DEBUG = LatinImeLogger.sDBG;
- final Resources res = getResources();
- mResources = res;
-
loadSettings();
-
- ImfUtils.setAdditionalInputMethodSubtypes(this, mCurrentSettings.getAdditionalSubtypes());
-
initSuggest();
- mDisplayOrientation = res.getConfiguration().orientation;
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.getInstance().init(this, mKeyboardSwitcher);
+ }
+ mDisplayOrientation = getResources().getConfiguration().orientation;
// Register to receive ringer mode change and network state change.
// Also receive installation and removal of a dictionary pack.
@@ -441,34 +439,28 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
registerReceiver(mReceiver, filter);
- final IntentFilter packageFilter = new IntentFilter();
- packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
- packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
- packageFilter.addDataScheme(SCHEME_PACKAGE);
- registerReceiver(mDictionaryPackInstallReceiver, packageFilter);
+ // TODO: The experimental version is not supported by the Dictionary Pack Service yet.
+ if (!ProductionFlag.IS_EXPERIMENTAL) {
+ final IntentFilter packageFilter = new IntentFilter();
+ packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
+ packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+ packageFilter.addDataScheme(SCHEME_PACKAGE);
+ registerReceiver(mDictionaryPackInstallReceiver, packageFilter);
- final IntentFilter newDictFilter = new IntentFilter();
- newDictFilter.addAction(
- DictionaryPackInstallBroadcastReceiver.NEW_DICTIONARY_INTENT_ACTION);
- registerReceiver(mDictionaryPackInstallReceiver, newDictFilter);
+ final IntentFilter newDictFilter = new IntentFilter();
+ newDictFilter.addAction(
+ DictionaryPackInstallBroadcastReceiver.NEW_DICTIONARY_INTENT_ACTION);
+ registerReceiver(mDictionaryPackInstallReceiver, newDictFilter);
+ }
}
// Has to be package-visible for unit tests
- /* package for test */
+ @UsedForTesting
void loadSettings() {
- // Note that the calling sequence of onCreate() and onCurrentInputMethodSubtypeChanged()
- // is not guaranteed. It may even be called at the same time on a different thread.
- if (null == mPrefs) mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
+ final Locale locale = mSubtypeSwitcher.getCurrentSubtypeLocale();
final InputAttributes inputAttributes =
new InputAttributes(getCurrentInputEditorInfo(), isFullscreenMode());
- final RunInLocale<SettingsValues> job = new RunInLocale<SettingsValues>() {
- @Override
- protected SettingsValues job(Resources res) {
- return new SettingsValues(mPrefs, inputAttributes, LatinIME.this);
- }
- };
- mCurrentSettings = job.runInLocale(mResources, mSubtypeSwitcher.getCurrentSubtypeLocale());
- mFeedbackManager = new AudioAndHapticFeedbackManager(this, mCurrentSettings);
+ mSettings.loadSettings(locale, inputAttributes);
resetContactsDictionary(null == mSuggest ? null : mSuggest.getContactsDictionary());
}
@@ -495,8 +487,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
}
mSuggest = new Suggest(this /* Context */, subtypeLocale,
this /* SuggestInitializationListener */);
- if (mCurrentSettings.mCorrectionEnabled) {
- mSuggest.setAutoCorrectionThreshold(mCurrentSettings.mAutoCorrectionThreshold);
+ if (mSettings.getCurrent().mCorrectionEnabled) {
+ mSuggest.setAutoCorrectionThreshold(mSettings.getCurrent().mAutoCorrectionThreshold);
}
mIsMainDictionaryAvailable = DictionaryFactory.isDictionaryAvailable(this, subtypeLocale);
@@ -510,10 +502,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
resetContactsDictionary(oldContactsDictionary);
- // Note that the calling sequence of onCreate() and onCurrentInputMethodSubtypeChanged()
- // is not guaranteed. It may even be called at the same time on a different thread.
- if (null == mPrefs) mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
- mUserHistoryDictionary = UserHistoryDictionary.getInstance(this, localeStr, mPrefs);
+ final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+ mUserHistoryDictionary = UserHistoryDictionary.getInstance(this, localeStr, prefs);
mSuggest.setUserHistoryDictionary(mUserHistoryDictionary);
}
@@ -526,7 +516,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
* @param oldContactsDictionary an optional dictionary to use, or null
*/
private void resetContactsDictionary(final ContactsBinaryDictionary oldContactsDictionary) {
- final boolean shouldSetDictionary = (null != mSuggest && mCurrentSettings.mUseContactsDict);
+ final boolean shouldSetDictionary =
+ (null != mSuggest && mSettings.getCurrent().mUseContactsDict);
final ContactsBinaryDictionary dictionaryToUse;
if (!shouldSetDictionary) {
@@ -570,8 +561,12 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
mSuggest.close();
mSuggest = null;
}
+ mSettings.onDestroy();
unregisterReceiver(mReceiver);
- unregisterReceiver(mDictionaryPackInstallReceiver);
+ // TODO: The experimental version is not supported by the Dictionary Pack Service yet.
+ if (!ProductionFlag.IS_EXPERIMENTAL) {
+ unregisterReceiver(mDictionaryPackInstallReceiver);
+ }
LatinImeLogger.commit();
LatinImeLogger.onDestroy();
super.onDestroy();
@@ -579,10 +574,6 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
@Override
public void onConfigurationChanged(final Configuration conf) {
- // System locale has been changed. Needs to reload keyboard.
- if (mSubtypeSwitcher.onConfigurationChanged(conf, this)) {
- loadKeyboard();
- }
// If orientation changed while predicting, commit the change
if (mDisplayOrientation != conf.orientation) {
mDisplayOrientation = conf.orientation;
@@ -648,7 +639,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
public void onCurrentInputMethodSubtypeChanged(final InputMethodSubtype subtype) {
// Note that the calling sequence of onCreate() and onCurrentInputMethodSubtypeChanged()
// is not guaranteed. It may even be called at the same time on a different thread.
- mSubtypeSwitcher.updateSubtype(subtype);
+ mSubtypeSwitcher.onSubtypeChanged(subtype);
loadKeyboard();
}
@@ -661,6 +652,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
super.onStartInputView(editorInfo, restarting);
final KeyboardSwitcher switcher = mKeyboardSwitcher;
final MainKeyboardView mainKeyboardView = switcher.getMainKeyboardView();
+ final SettingsValues currentSettings = mSettings.getCurrent();
if (editorInfo == null) {
Log.e(TAG, "Null EditorInfo in onStartInputView()");
@@ -681,7 +673,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
+ ((editorInfo.inputType & InputType.TYPE_TEXT_FLAG_CAP_WORDS) != 0));
}
if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_onStartInputViewInternal(editorInfo, mPrefs);
+ final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+ ResearchLogger.latinIME_onStartInputViewInternal(editorInfo, prefs);
}
if (InputAttributes.inPrivateImeOptions(null, NO_MICROPHONE_COMPAT, editorInfo)) {
Log.w(TAG, "Deprecated private IME option specified: "
@@ -713,18 +706,10 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
accessUtils.onStartInputViewInternal(mainKeyboardView, editorInfo, restarting);
}
- final boolean inputTypeChanged = !mCurrentSettings.isSameInputType(editorInfo);
+ final boolean inputTypeChanged = !currentSettings.isSameInputType(editorInfo);
final boolean isDifferentTextField = !restarting || inputTypeChanged;
if (isDifferentTextField) {
- final boolean currentSubtypeEnabled = mSubtypeSwitcher
- .updateParametersOnStartInputViewAndReturnIfCurrentSubtypeEnabled();
- if (!currentSubtypeEnabled) {
- // Current subtype is disabled. Needs to update subtype and keyboard.
- final InputMethodSubtype newSubtype = ImfUtils.getCurrentInputMethodSubtype(
- this, mSubtypeSwitcher.getNoLanguageSubtype());
- mSubtypeSwitcher.updateSubtype(newSubtype);
- loadKeyboard();
- }
+ mSubtypeSwitcher.updateParametersOnStartInputView();
}
// The EditorInfo might have a flag that affects fullscreen mode.
@@ -738,12 +723,14 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
resetComposingState(true /* alsoResetLastComposedWord */);
mDeleteCount = 0;
mSpaceState = SPACE_STATE_NONE;
+ mCurrentlyPressedHardwareKeys.clear();
if (mSuggestionStripView != null) {
// This will set the punctuation suggestions if next word suggestion is off;
// otherwise it will clear the suggestion strip.
setPunctuationSuggestions();
}
+ mSuggestedWords = SuggestedWords.EMPTY;
mConnection.resetCachesUponCursorMove(editorInfo.initialSelStart);
@@ -751,11 +738,11 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
mainKeyboardView.closing();
loadSettings();
- if (mSuggest != null && mCurrentSettings.mCorrectionEnabled) {
- mSuggest.setAutoCorrectionThreshold(mCurrentSettings.mAutoCorrectionThreshold);
+ if (mSuggest != null && currentSettings.mCorrectionEnabled) {
+ mSuggest.setAutoCorrectionThreshold(currentSettings.mAutoCorrectionThreshold);
}
- switcher.loadKeyboard(editorInfo, mCurrentSettings);
+ switcher.loadKeyboard(editorInfo, currentSettings);
} else if (restarting) {
// TODO: Come up with a more comprehensive way to reset the keyboard layout when
// a keyboard layout set doesn't get reloaded in this method.
@@ -773,21 +760,25 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
mLastSelectionEnd = editorInfo.initialSelEnd;
mHandler.cancelUpdateSuggestionStrip();
- mHandler.cancelDoubleSpacesTimer();
+ mHandler.cancelDoubleSpacePeriodTimer();
mainKeyboardView.setMainDictionaryAvailability(mIsMainDictionaryAvailable);
- mainKeyboardView.setKeyPreviewPopupEnabled(mCurrentSettings.mKeyPreviewPopupOn,
- mCurrentSettings.mKeyPreviewPopupDismissDelay);
- mainKeyboardView.setGestureHandlingEnabledByUser(mCurrentSettings.mGestureInputEnabled);
- mainKeyboardView.setGesturePreviewMode(mCurrentSettings.mGesturePreviewTrailEnabled,
- mCurrentSettings.mGestureFloatingPreviewTextEnabled);
+ mainKeyboardView.setKeyPreviewPopupEnabled(currentSettings.mKeyPreviewPopupOn,
+ currentSettings.mKeyPreviewPopupDismissDelay);
+ mainKeyboardView.setSlidingKeyInputPreviewEnabled(
+ currentSettings.mSlidingKeyInputPreviewEnabled);
+ mainKeyboardView.setGestureHandlingEnabledByUser(
+ currentSettings.mGestureInputEnabled);
+ mainKeyboardView.setGesturePreviewMode(currentSettings.mGesturePreviewTrailEnabled,
+ currentSettings.mGestureFloatingPreviewTextEnabled);
// If we have a user dictionary addition in progress, we should check now if we should
// replace the previously committed string with the word that has actually been added
// to the user dictionary.
if (null != mPositionalInfoForUserDictPendingAddition
&& mPositionalInfoForUserDictPendingAddition.tryReplaceWithActualWord(
- mConnection, editorInfo, mLastSelectionEnd)) {
+ mConnection, editorInfo, mLastSelectionEnd,
+ mSubtypeSwitcher.getCurrentSubtypeLocale())) {
mPositionalInfoForUserDictPendingAddition = null;
}
// If tryReplaceWithActualWord returns false, we don't know what word was
@@ -821,10 +812,6 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
super.onFinishInput();
LatinImeLogger.commit();
- if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.getInstance().latinIME_onFinishInputInternal();
- }
-
final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
if (mainKeyboardView != null) {
mainKeyboardView.closing();
@@ -840,6 +827,10 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
}
// Remove pending messages related to update suggestions
mHandler.cancelUpdateSuggestionStrip();
+ resetComposingState(true /* alsoResetLastComposedWord */);
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.getInstance().latinIME_onFinishInputViewInternal();
+ }
}
@Override
@@ -938,7 +929,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
*/
@Override
public void onExtractedTextClicked() {
- if (mCurrentSettings.isSuggestionsRequested(mDisplayOrientation)) return;
+ if (mSettings.getCurrent().isSuggestionsRequested(mDisplayOrientation)) return;
super.onExtractedTextClicked();
}
@@ -954,7 +945,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
*/
@Override
public void onExtractedCursorMovement(final int dx, final int dy) {
- if (mCurrentSettings.isSuggestionsRequested(mDisplayOrientation)) return;
+ if (mSettings.getCurrent().isSuggestionsRequested(mDisplayOrientation)) return;
super.onExtractedCursorMovement(dx, dy);
}
@@ -964,6 +955,10 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
LatinImeLogger.commit();
mKeyboardSwitcher.onHideWindow();
+ if (AccessibilityUtils.getInstance().isAccessibilityEnabled()) {
+ AccessibleKeyboardViewProxy.getInstance().onHideWindow();
+ }
+
if (TRACE) Debug.stopMethodTracing();
if (mOptionsDialog != null && mOptionsDialog.isShowing()) {
mOptionsDialog.dismiss();
@@ -982,7 +977,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
}
}
}
- if (!mCurrentSettings.isApplicationSpecifiedCompletionsOn()) return;
+ if (!mSettings.getCurrent().isApplicationSpecifiedCompletionsOn()) return;
mApplicationSpecifiedCompletions = applicationSpecifiedCompletions;
if (applicationSpecifiedCompletions == null) {
clearSuggestionStrip();
@@ -1004,11 +999,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
false /* isPrediction */);
// When in fullscreen mode, show completions generated by the application
final boolean isAutoCorrection = false;
- setSuggestionStrip(suggestedWords, isAutoCorrection);
+ setSuggestedWords(suggestedWords, isAutoCorrection);
setAutoCorrectionIndicator(isAutoCorrection);
- // TODO: is this the right thing to do? What should we auto-correct to in
- // this case? This says to keep whatever the user typed.
- mWordComposer.setAutoCorrection(mWordComposer.getTypedWord());
setSuggestionStripShown(true);
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.latinIME_onDisplayCompletions(applicationSpecifiedCompletions);
@@ -1050,7 +1042,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
}
final int keyboardHeight = mainKeyboardView.getHeight();
final int suggestionsHeight = mSuggestionsContainer.getHeight();
- final int displayHeight = mResources.getDisplayMetrics().heightPixels;
+ final int displayHeight = getResources().getDisplayMetrics().heightPixels;
final Rect rect = new Rect();
mKeyPreviewBackingView.getWindowVisibleDisplayFrame(rect);
final int notificationBarHeight = rect.top;
@@ -1080,12 +1072,13 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
final int suggestionsHeight = (mSuggestionsContainer.getVisibility() == View.GONE) ? 0
: mSuggestionsContainer.getHeight();
final int extraHeight = extractHeight + backingHeight + suggestionsHeight;
- int touchY = extraHeight;
+ int visibleTopY = extraHeight;
// Need to set touchable region only if input view is being shown
if (mainKeyboardView.isShown()) {
if (mSuggestionsContainer.getVisibility() == View.VISIBLE) {
- touchY -= suggestionsHeight;
+ visibleTopY -= suggestionsHeight;
}
+ final int touchY = mainKeyboardView.isShowingMoreKeysPanel() ? 0 : visibleTopY;
final int touchWidth = mainKeyboardView.getWidth();
final int touchHeight = mainKeyboardView.getHeight() + extraHeight
// Extend touchable region below the keyboard.
@@ -1093,15 +1086,15 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
outInsets.touchableInsets = InputMethodService.Insets.TOUCHABLE_INSETS_REGION;
outInsets.touchableRegion.set(0, touchY, touchWidth, touchHeight);
}
- outInsets.contentTopInsets = touchY;
- outInsets.visibleTopInsets = touchY;
+ outInsets.contentTopInsets = visibleTopY;
+ outInsets.visibleTopInsets = visibleTopY;
}
@Override
public boolean onEvaluateFullscreenMode() {
// Reread resource value here, because this method is called by framework anytime as needed.
final boolean isFullscreenModeAllowed =
- mCurrentSettings.isFullscreenModeAllowed(getResources());
+ Settings.readUseFullscreenMode(getResources());
if (super.onEvaluateFullscreenMode() && isFullscreenModeAllowed) {
// TODO: Remove this hack. Actually we should not really assume NO_EXTRACT_UI
// implies NO_FULLSCREEN. However, the framework mistakenly does. i.e. NO_EXTRACT_UI
@@ -1128,10 +1121,10 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// the composing word, reset the last composed word, tell the inputconnection about it.
private void resetEntireInputState(final int newCursorPosition) {
resetComposingState(true /* alsoResetLastComposedWord */);
- if (mCurrentSettings.mBigramPredictionEnabled) {
+ if (mSettings.getCurrent().mBigramPredictionEnabled) {
clearSuggestionStrip();
} else {
- setSuggestionStrip(mCurrentSettings.mSuggestPuncList, false);
+ setSuggestedWords(mSettings.getCurrent().mSuggestPuncList, false);
}
mConnection.resetCachesUponCursorMove(newCursorPosition);
}
@@ -1144,17 +1137,20 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
private void commitTyped(final String separatorString) {
if (!mWordComposer.isComposingWord()) return;
- final CharSequence typedWord = mWordComposer.getTypedWord();
+ final String typedWord = mWordComposer.getTypedWord();
if (typedWord.length() > 0) {
commitChosenWord(typedWord, LastComposedWord.COMMIT_TYPE_USER_TYPED_WORD,
separatorString);
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.getInstance().onWordFinished(typedWord, mWordComposer.isBatchMode());
+ }
}
}
// Called from the KeyboardSwitcher which needs to know auto caps state to display
// the right layout.
public int getCurrentAutoCapsState() {
- if (!mCurrentSettings.mAutoCap) return Constants.TextUtils.CAP_MODE_OFF;
+ if (!mSettings.getCurrent().mAutoCap) return Constants.TextUtils.CAP_MODE_OFF;
final EditorInfo ei = getCurrentInputEditorInfo();
if (ei == null) return Constants.TextUtils.CAP_MODE_OFF;
@@ -1178,46 +1174,53 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
}
private void swapSwapperAndSpace() {
- CharSequence lastTwo = mConnection.getTextBeforeCursor(2, 0);
+ final CharSequence lastTwo = mConnection.getTextBeforeCursor(2, 0);
// It is guaranteed lastTwo.charAt(1) is a swapper - else this method is not called.
if (lastTwo != null && lastTwo.length() == 2
- && lastTwo.charAt(0) == Keyboard.CODE_SPACE) {
+ && lastTwo.charAt(0) == Constants.CODE_SPACE) {
mConnection.deleteSurroundingText(2, 0);
- mConnection.commitText(lastTwo.charAt(1) + " ", 1);
+ final String text = lastTwo.charAt(1) + " ";
+ mConnection.commitText(text, 1);
if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_swapSwapperAndSpace();
+ ResearchLogger.latinIME_swapSwapperAndSpace(lastTwo, text);
}
mKeyboardSwitcher.updateShiftState();
}
}
- private boolean maybeDoubleSpace() {
- if (!mCurrentSettings.mCorrectionEnabled) return false;
- if (!mHandler.isAcceptingDoubleSpaces()) return false;
+ private boolean maybeDoubleSpacePeriod() {
+ if (!mSettings.getCurrent().mCorrectionEnabled) return false;
+ if (!mSettings.getCurrent().mUseDoubleSpacePeriod) return false;
+ if (!mHandler.isAcceptingDoubleSpacePeriod()) return false;
final CharSequence lastThree = mConnection.getTextBeforeCursor(3, 0);
if (lastThree != null && lastThree.length() == 3
- && canBeFollowedByPeriod(lastThree.charAt(0))
- && lastThree.charAt(1) == Keyboard.CODE_SPACE
- && lastThree.charAt(2) == Keyboard.CODE_SPACE) {
- mHandler.cancelDoubleSpacesTimer();
+ && canBeFollowedByDoubleSpacePeriod(lastThree.charAt(0))
+ && lastThree.charAt(1) == Constants.CODE_SPACE
+ && lastThree.charAt(2) == Constants.CODE_SPACE) {
+ mHandler.cancelDoubleSpacePeriodTimer();
mConnection.deleteSurroundingText(2, 0);
- mConnection.commitText(". ", 1);
+ final String textToInsert = ". ";
+ mConnection.commitText(textToInsert, 1);
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.latinIME_maybeDoubleSpacePeriod(textToInsert,
+ false /* isBatchMode */);
+ }
mKeyboardSwitcher.updateShiftState();
return true;
}
return false;
}
- private static boolean canBeFollowedByPeriod(final int codePoint) {
+ private static boolean canBeFollowedByDoubleSpacePeriod(final int codePoint) {
// TODO: Check again whether there really ain't a better way to check this.
// TODO: This should probably be language-dependant...
return Character.isLetterOrDigit(codePoint)
- || codePoint == Keyboard.CODE_SINGLE_QUOTE
- || codePoint == Keyboard.CODE_DOUBLE_QUOTE
- || codePoint == Keyboard.CODE_CLOSING_PARENTHESIS
- || codePoint == Keyboard.CODE_CLOSING_SQUARE_BRACKET
- || codePoint == Keyboard.CODE_CLOSING_CURLY_BRACKET
- || codePoint == Keyboard.CODE_CLOSING_ANGLE_BRACKET;
+ || codePoint == Constants.CODE_SINGLE_QUOTE
+ || codePoint == Constants.CODE_DOUBLE_QUOTE
+ || codePoint == Constants.CODE_CLOSING_PARENTHESIS
+ || codePoint == Constants.CODE_CLOSING_SQUARE_BRACKET
+ || codePoint == Constants.CODE_CLOSING_CURLY_BRACKET
+ || codePoint == Constants.CODE_CLOSING_ANGLE_BRACKET;
}
// Callback for the {@link SuggestionStripView}, to call when the "add to dictionary" hint is
@@ -1229,10 +1232,17 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
mPositionalInfoForUserDictPendingAddition = null;
return;
}
+ final String wordToEdit;
+ if (CapsModeUtils.isAutoCapsMode(mLastComposedWord.mCapitalizedMode)) {
+ wordToEdit = word.toLowerCase(mSubtypeSwitcher.getCurrentSubtypeLocale());
+ } else {
+ wordToEdit = word;
+ }
mPositionalInfoForUserDictPendingAddition =
new PositionalInfoForUserDictPendingAddition(
- word, mLastSelectionEnd, getCurrentInputEditorInfo());
- mUserDictionary.addWordToUserDictionary(word, 128);
+ wordToEdit, mLastSelectionEnd, getCurrentInputEditorInfo(),
+ mLastComposedWord.mCapitalizedMode);
+ mUserDictionary.addWordToUserDictionary(wordToEdit);
}
public void onWordAddedToUserDictionary(final String newSpelling) {
@@ -1245,7 +1255,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
}
mPositionalInfoForUserDictPendingAddition.setActualWordBeingAdded(newSpelling);
if (mPositionalInfoForUserDictPendingAddition.tryReplaceWithActualWord(
- mConnection, getCurrentInputEditorInfo(), mLastSelectionEnd)) {
+ mConnection, getCurrentInputEditorInfo(), mLastSelectionEnd,
+ mSubtypeSwitcher.getCurrentSubtypeLocale())) {
mPositionalInfoForUserDictPendingAddition = null;
}
}
@@ -1267,9 +1278,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
if (isShowingOptionDialog()) return false;
switch (requestCode) {
case CODE_SHOW_INPUT_METHOD_PICKER:
- if (ImfUtils.hasMultipleEnabledIMEsOrSubtypes(
- this, true /* include aux subtypes */)) {
- mImm.showInputMethodPicker();
+ if (mRichImm.hasMultipleEnabledIMEsOrSubtypes(true /* include aux subtypes */)) {
+ mRichImm.getInputMethodManager().showInputMethodPicker();
return true;
}
return false;
@@ -1281,10 +1291,6 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
return mOptionsDialog != null && mOptionsDialog.isShowing();
}
- private static int getActionId(final Keyboard keyboard) {
- return keyboard != null ? keyboard.mId.imeActionId() : EditorInfo.IME_ACTION_NONE;
- }
-
private void performEditorAction(final int actionId) {
mConnection.performEditorAction(actionId);
}
@@ -1292,11 +1298,11 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// TODO: Revise the language switch key behavior to make it much smarter and more reasonable.
private void handleLanguageSwitchKey() {
final IBinder token = getWindow().getWindow().getAttributes().token;
- if (mCurrentSettings.mIncludesOtherImesInLanguageSwitchList) {
- mImm.switchToNextInputMethod(token, false /* onlyCurrentIme */);
+ if (mSettings.getCurrent().mIncludesOtherImesInLanguageSwitchList) {
+ mRichImm.switchToNextInputMethod(token, false /* onlyCurrentIme */);
return;
}
- mSubtypeState.switchSubtype(token, mImm, this);
+ mSubtypeState.switchSubtype(token, mRichImm);
}
private void sendDownUpKeyEventForBackwardCompatibility(final int code) {
@@ -1310,20 +1316,18 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
}
private void sendKeyCodePoint(final int code) {
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.latinIME_sendKeyCodePoint(code);
+ }
// TODO: Remove this special handling of digit letters.
// For backward compatibility. See {@link InputMethodService#sendKeyChar(char)}.
if (code >= '0' && code <= '9') {
sendDownUpKeyEventForBackwardCompatibility(code - '0' + KeyEvent.KEYCODE_0);
- if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_sendKeyCodePoint(code);
- }
return;
}
- // 16 is android.os.Build.VERSION_CODES.JELLY_BEAN but we can't write it because
- // we want to be able to compile against the Ice Cream Sandwich SDK.
- if (Keyboard.CODE_ENTER == code && mTargetApplicationInfo != null
- && mTargetApplicationInfo.targetSdkVersion < 16) {
+ if (Constants.CODE_ENTER == code && mTargetApplicationInfo != null
+ && mTargetApplicationInfo.targetSdkVersion < VERSION_CODES.JELLY_BEAN) {
// Backward compatibility mode. Before Jelly bean, the keyboard would simulate
// a hardware keyboard event on pressing enter or delete. This is bad for many
// reasons (there are race conditions with commits) but some applications are
@@ -1338,8 +1342,11 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// Implementation of {@link KeyboardActionListener}.
@Override
public void onCodeInput(final int primaryCode, final int x, final int y) {
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.latinIME_onCodeInput(primaryCode, x, y);
+ }
final long when = SystemClock.uptimeMillis();
- if (primaryCode != Keyboard.CODE_DELETE || when > mLastKeyTime + QUICK_PRESS) {
+ if (primaryCode != Constants.CODE_DELETE || when > mLastKeyTime + QUICK_PRESS) {
mDeleteCount = 0;
}
mLastKeyTime = when;
@@ -1353,115 +1360,147 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
final int spaceState = mSpaceState;
if (!mWordComposer.isComposingWord()) mIsAutoCorrectionIndicatorOn = false;
- // TODO: Consolidate the double space timer, mLastKeyTime, and the space state.
- if (primaryCode != Keyboard.CODE_SPACE) {
- mHandler.cancelDoubleSpacesTimer();
+ // TODO: Consolidate the double-space period timer, mLastKeyTime, and the space state.
+ if (primaryCode != Constants.CODE_SPACE) {
+ mHandler.cancelDoubleSpacePeriodTimer();
}
boolean didAutoCorrect = false;
switch (primaryCode) {
- case Keyboard.CODE_DELETE:
+ case Constants.CODE_DELETE:
mSpaceState = SPACE_STATE_NONE;
handleBackspace(spaceState);
mDeleteCount++;
mExpectingUpdateSelection = true;
LatinImeLogger.logOnDelete(x, y);
break;
- case Keyboard.CODE_SHIFT:
- case Keyboard.CODE_SWITCH_ALPHA_SYMBOL:
+ case Constants.CODE_SHIFT:
+ case Constants.CODE_SWITCH_ALPHA_SYMBOL:
// Shift and symbol key is handled in onPressKey() and onReleaseKey().
break;
- case Keyboard.CODE_SETTINGS:
+ case Constants.CODE_SETTINGS:
onSettingsKeyPressed();
break;
- case Keyboard.CODE_SHORTCUT:
+ case Constants.CODE_SHORTCUT:
mSubtypeSwitcher.switchToShortcutIME(this);
break;
- case Keyboard.CODE_ACTION_ENTER:
- performEditorAction(getActionId(switcher.getKeyboard()));
- break;
- case Keyboard.CODE_ACTION_NEXT:
+ case Constants.CODE_ACTION_NEXT:
performEditorAction(EditorInfo.IME_ACTION_NEXT);
break;
- case Keyboard.CODE_ACTION_PREVIOUS:
+ case Constants.CODE_ACTION_PREVIOUS:
performEditorAction(EditorInfo.IME_ACTION_PREVIOUS);
break;
- case Keyboard.CODE_LANGUAGE_SWITCH:
+ case Constants.CODE_LANGUAGE_SWITCH:
handleLanguageSwitchKey();
break;
- case Keyboard.CODE_RESEARCH:
+ case Constants.CODE_RESEARCH:
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.getInstance().onResearchKeySelected(this);
}
break;
- default:
- mSpaceState = SPACE_STATE_NONE;
- if (mCurrentSettings.isWordSeparator(primaryCode)) {
- didAutoCorrect = handleSeparator(primaryCode, x, y, spaceState);
+ case Constants.CODE_ENTER:
+ final EditorInfo editorInfo = getCurrentInputEditorInfo();
+ final int imeOptionsActionId =
+ InputTypeUtils.getImeOptionsActionIdFromEditorInfo(editorInfo);
+ if (InputTypeUtils.IME_ACTION_CUSTOM_LABEL == imeOptionsActionId) {
+ // Either we have an actionLabel and we should performEditorAction with actionId
+ // regardless of its value.
+ performEditorAction(editorInfo.actionId);
+ } else if (EditorInfo.IME_ACTION_NONE != imeOptionsActionId) {
+ // We didn't have an actionLabel, but we had another action to execute.
+ // EditorInfo.IME_ACTION_NONE explicitly means no action. In contrast,
+ // EditorInfo.IME_ACTION_UNSPECIFIED is the default value for an action, so it
+ // means there should be an action and the app didn't bother to set a specific
+ // code for it - presumably it only handles one. It does not have to be treated
+ // in any specific way: anything that is not IME_ACTION_NONE should be sent to
+ // performEditorAction.
+ performEditorAction(imeOptionsActionId);
} else {
- if (SPACE_STATE_PHANTOM == spaceState) {
- if (ProductionFlag.IS_INTERNAL) {
- if (mWordComposer.isComposingWord() && mWordComposer.isBatchMode()) {
- Stats.onAutoCorrection(
- "", mWordComposer.getTypedWord(), " ", mWordComposer);
- }
- }
- commitTyped(LastComposedWord.NOT_A_SEPARATOR);
- }
- final int keyX, keyY;
- final Keyboard keyboard = mKeyboardSwitcher.getKeyboard();
- if (keyboard != null && keyboard.hasProximityCharsCorrection(primaryCode)) {
- keyX = x;
- keyY = y;
- } else {
- keyX = Constants.NOT_A_COORDINATE;
- keyY = Constants.NOT_A_COORDINATE;
- }
- handleCharacter(primaryCode, keyX, keyY, spaceState);
+ // No action label, and the action from imeOptions is NONE: this is a regular
+ // enter key that should input a carriage return.
+ didAutoCorrect = handleNonSpecialCharacter(Constants.CODE_ENTER, x, y, spaceState);
}
- mExpectingUpdateSelection = true;
+ break;
+ case Constants.CODE_SHIFT_ENTER:
+ didAutoCorrect = handleNonSpecialCharacter(Constants.CODE_ENTER, x, y, spaceState);
+ break;
+ default:
+ didAutoCorrect = handleNonSpecialCharacter(primaryCode, x, y, spaceState);
break;
}
switcher.onCodeInput(primaryCode);
// Reset after any single keystroke, except shift and symbol-shift
- if (!didAutoCorrect && primaryCode != Keyboard.CODE_SHIFT
- && primaryCode != Keyboard.CODE_SWITCH_ALPHA_SYMBOL)
+ if (!didAutoCorrect && primaryCode != Constants.CODE_SHIFT
+ && primaryCode != Constants.CODE_SWITCH_ALPHA_SYMBOL)
mLastComposedWord.deactivate();
- if (Keyboard.CODE_DELETE != primaryCode) {
+ if (Constants.CODE_DELETE != primaryCode) {
mEnteredText = null;
}
mConnection.endBatchEdit();
- if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_onCodeInput(primaryCode, x, y);
+ }
+
+ private boolean handleNonSpecialCharacter(final int primaryCode, final int x, final int y,
+ final int spaceState) {
+ mSpaceState = SPACE_STATE_NONE;
+ final boolean didAutoCorrect;
+ if (mSettings.getCurrent().isWordSeparator(primaryCode)) {
+ didAutoCorrect = handleSeparator(primaryCode, x, y, spaceState);
+ } else {
+ didAutoCorrect = false;
+ if (SPACE_STATE_PHANTOM == spaceState) {
+ if (ProductionFlag.IS_INTERNAL) {
+ if (mWordComposer.isComposingWord() && mWordComposer.isBatchMode()) {
+ Stats.onAutoCorrection(
+ "", mWordComposer.getTypedWord(), " ", mWordComposer);
+ }
+ }
+ commitTyped(LastComposedWord.NOT_A_SEPARATOR);
+ }
+ final int keyX, keyY;
+ final Keyboard keyboard = mKeyboardSwitcher.getKeyboard();
+ if (keyboard != null && keyboard.hasProximityCharsCorrection(primaryCode)) {
+ keyX = x;
+ keyY = y;
+ } else {
+ keyX = Constants.NOT_A_COORDINATE;
+ keyY = Constants.NOT_A_COORDINATE;
+ }
+ handleCharacter(primaryCode, keyX, keyY, spaceState);
}
+ mExpectingUpdateSelection = true;
+ return didAutoCorrect;
}
// Called from PointerTracker through the KeyboardActionListener interface
@Override
- public void onTextInput(final CharSequence rawText) {
+ public void onTextInput(final String rawText) {
mConnection.beginBatchEdit();
if (mWordComposer.isComposingWord()) {
- commitCurrentAutoCorrection(rawText.toString());
+ commitCurrentAutoCorrection(rawText);
} else {
resetComposingState(true /* alsoResetLastComposedWord */);
}
mHandler.postUpdateSuggestionStrip();
- final CharSequence text = specificTldProcessingOnTextInput(rawText);
+ final String text = specificTldProcessingOnTextInput(rawText);
if (SPACE_STATE_PHANTOM == mSpaceState) {
promotePhantomSpace();
}
mConnection.commitText(text, 1);
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.latinIME_onTextInput(text, false /* isBatchMode */);
+ }
mConnection.endBatchEdit();
// Space state must be updated before calling updateShiftState
mSpaceState = SPACE_STATE_NONE;
mKeyboardSwitcher.updateShiftState();
- mKeyboardSwitcher.onCodeInput(Keyboard.CODE_OUTPUT_TEXT);
+ mKeyboardSwitcher.onCodeInput(Constants.CODE_OUTPUT_TEXT);
mEnteredText = text;
}
@Override
public void onStartBatchInput() {
- BatchInputUpdater.getInstance().onStartBatchInput();
+ BatchInputUpdater.getInstance().onStartBatchInput(this);
+ mHandler.cancelUpdateSuggestionStrip();
mConnection.beginBatchEdit();
if (mWordComposer.isComposingWord()) {
if (ProductionFlag.IS_INTERNAL) {
@@ -1469,7 +1508,10 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
Stats.onAutoCorrection("", mWordComposer.getTypedWord(), " ", mWordComposer);
}
}
- if (mWordComposer.size() <= 1) {
+ final int wordComposerSize = mWordComposer.size();
+ // Since isComposingWord() is true, the size is at least 1.
+ final int lastChar = mWordComposer.getCodeAt(wordComposerSize - 1);
+ if (wordComposerSize <= 1) {
// We auto-correct the previous (typed, not gestured) string iff it's one character
// long. The reason for this is, even in the middle of gesture typing, you'll still
// tap one-letter words and you want them auto-corrected (typically, "i" in English
@@ -1483,16 +1525,17 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
}
mExpectingUpdateSelection = true;
// The following is necessary for the case where the user typed something but didn't
- // manual pick it and didn't input any separator.
- mSpaceState = SPACE_STATE_PHANTOM;
+ // manual pick it and didn't input any separator: we want to put a space between what
+ // has been entered and the coming gesture input result, so we go into phantom space
+ // state, which will be promoted to a space when the gesture result is committed. But if
+ // the current input ends in a word connector on the other hand, then we want to have
+ // the next input stick to the current input so we don't switch to phantom space state.
+ if (!mSettings.getCurrent().isWordConnector(lastChar)) {
+ mSpaceState = SPACE_STATE_PHANTOM;
+ }
} else {
final int codePointBeforeCursor = mConnection.getCodePointBeforeCursor();
- // TODO: reverse this logic. We should have the means to determine whether a character
- // should usually be followed by a space, and it should be more readable.
- if (Constants.NOT_A_CODE != codePointBeforeCursor
- && !Character.isWhitespace(codePointBeforeCursor)
- && !mCurrentSettings.isPhantomSpacePromotingSymbol(codePointBeforeCursor)
- && !mCurrentSettings.isWeakSpaceStripper(codePointBeforeCursor)) {
+ if (mSettings.getCurrent().isUsuallyFollowedBySpace(codePointBeforeCursor)) {
mSpaceState = SPACE_STATE_PHANTOM;
}
}
@@ -1503,7 +1546,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
private static final class BatchInputUpdater implements Handler.Callback {
private final Handler mHandler;
private LatinIME mLatinIme;
- private boolean mInBatchInput; // synchornized using "this".
+ private boolean mInBatchInput; // synchronized using "this".
private BatchInputUpdater() {
final HandlerThread handlerThread = new HandlerThread(
@@ -1527,33 +1570,32 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
public boolean handleMessage(final Message msg) {
switch (msg.what) {
case MSG_UPDATE_GESTURE_PREVIEW_AND_SUGGESTION_STRIP:
- updateBatchInput((InputPointers)msg.obj, mLatinIme);
+ updateBatchInput((InputPointers)msg.obj);
break;
}
return true;
}
// Run in the UI thread.
- public synchronized void onStartBatchInput() {
+ public synchronized void onStartBatchInput(final LatinIME latinIme) {
+ mHandler.removeMessages(MSG_UPDATE_GESTURE_PREVIEW_AND_SUGGESTION_STRIP);
+ mLatinIme = latinIme;
mInBatchInput = true;
}
// Run in the Handler thread.
- private synchronized void updateBatchInput(final InputPointers batchPointers,
- final LatinIME latinIme) {
+ private synchronized void updateBatchInput(final InputPointers batchPointers) {
if (!mInBatchInput) {
- // Batch input has ended while the message was being delivered.
+ // Batch input has ended or canceled while the message was being delivered.
return;
}
- final SuggestedWords suggestedWords = getSuggestedWordsGestureLocked(
- batchPointers, latinIme);
- latinIme.mHandler.showGesturePreviewAndSuggestionStrip(
+ final SuggestedWords suggestedWords = getSuggestedWordsGestureLocked(batchPointers);
+ mLatinIme.mHandler.showGesturePreviewAndSuggestionStrip(
suggestedWords, false /* dismissGestureFloatingPreviewText */);
}
// Run in the UI thread.
- public void onUpdateBatchInput(final InputPointers batchPointers, final LatinIME latinIme) {
- mLatinIme = latinIme;
+ public void onUpdateBatchInput(final InputPointers batchPointers) {
if (mHandler.hasMessages(MSG_UPDATE_GESTURE_PREVIEW_AND_SUGGESTION_STRIP)) {
return;
}
@@ -1562,33 +1604,42 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
.sendToTarget();
}
+ public synchronized void onCancelBatchInput() {
+ mInBatchInput = false;
+ mLatinIme.mHandler.showGesturePreviewAndSuggestionStrip(
+ SuggestedWords.EMPTY, true /* dismissGestureFloatingPreviewText */);
+ }
+
// Run in the UI thread.
- public synchronized SuggestedWords onEndBatchInput(final InputPointers batchPointers,
- final LatinIME latinIme) {
+ public synchronized SuggestedWords onEndBatchInput(final InputPointers batchPointers) {
mInBatchInput = false;
- final SuggestedWords suggestedWords = getSuggestedWordsGestureLocked(
- batchPointers, latinIme);
- latinIme.mHandler.showGesturePreviewAndSuggestionStrip(
+ final SuggestedWords suggestedWords = getSuggestedWordsGestureLocked(batchPointers);
+ mLatinIme.mHandler.showGesturePreviewAndSuggestionStrip(
suggestedWords, true /* dismissGestureFloatingPreviewText */);
return suggestedWords;
}
// {@link LatinIME#getSuggestedWords(int)} method calls with same session id have to
// be synchronized.
- private static SuggestedWords getSuggestedWordsGestureLocked(
- final InputPointers batchPointers, final LatinIME latinIme) {
- latinIme.mWordComposer.setBatchInputPointers(batchPointers);
- return latinIme.getSuggestedWords(Suggest.SESSION_GESTURE);
+ private SuggestedWords getSuggestedWordsGestureLocked(final InputPointers batchPointers) {
+ mLatinIme.mWordComposer.setBatchInputPointers(batchPointers);
+ final SuggestedWords suggestedWords =
+ mLatinIme.getSuggestedWords(Suggest.SESSION_GESTURE);
+ final int suggestionCount = suggestedWords.size();
+ if (suggestionCount <= 1) {
+ final String mostProbableSuggestion = (suggestionCount == 0) ? null
+ : suggestedWords.getWord(0);
+ return mLatinIme.getOlderSuggestions(mostProbableSuggestion);
+ }
+ return suggestedWords;
}
}
private void showGesturePreviewAndSuggestionStrip(final SuggestedWords suggestedWords,
final boolean dismissGestureFloatingPreviewText) {
- final String batchInputText = (suggestedWords.size() > 0)
- ? suggestedWords.getWord(0) : null;
- final KeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
- mainKeyboardView.showGestureFloatingPreviewText(batchInputText);
showSuggestionStrip(suggestedWords, null);
+ final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
+ mainKeyboardView.showGestureFloatingPreviewText(suggestedWords);
if (dismissGestureFloatingPreviewText) {
mainKeyboardView.dismissGestureFloatingPreviewText();
}
@@ -1596,15 +1647,15 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
@Override
public void onUpdateBatchInput(final InputPointers batchPointers) {
- BatchInputUpdater.getInstance().onUpdateBatchInput(batchPointers, this);
+ BatchInputUpdater.getInstance().onUpdateBatchInput(batchPointers);
}
@Override
public void onEndBatchInput(final InputPointers batchPointers) {
final SuggestedWords suggestedWords = BatchInputUpdater.getInstance().onEndBatchInput(
- batchPointers, this);
- final String batchInputText = (suggestedWords.size() > 0)
- ? suggestedWords.getWord(0) : null;
+ batchPointers);
+ final String batchInputText = suggestedWords.isEmpty()
+ ? null : suggestedWords.getWord(0);
if (TextUtils.isEmpty(batchInputText)) {
return;
}
@@ -1616,13 +1667,16 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
mConnection.setComposingText(batchInputText, 1);
mExpectingUpdateSelection = true;
mConnection.endBatchEdit();
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.latinIME_onEndBatchInput(batchInputText, 0, suggestedWords);
+ }
// Space state must be updated before calling updateShiftState
mSpaceState = SPACE_STATE_PHANTOM;
mKeyboardSwitcher.updateShiftState();
}
- private CharSequence specificTldProcessingOnTextInput(final CharSequence text) {
- if (text.length() <= 1 || text.charAt(0) != Keyboard.CODE_PERIOD
+ private String specificTldProcessingOnTextInput(final String text) {
+ if (text.length() <= 1 || text.charAt(0) != Constants.CODE_PERIOD
|| !Character.isLetter(text.charAt(1))) {
// Not a tld: do nothing.
return text;
@@ -1633,8 +1687,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// TODO: use getCodePointBeforeCursor instead to improve performance and simplify the code
final CharSequence lastOne = mConnection.getTextBeforeCursor(1, 0);
if (lastOne != null && lastOne.length() == 1
- && lastOne.charAt(0) == Keyboard.CODE_PERIOD) {
- return text.subSequence(1, text.length());
+ && lastOne.charAt(0) == Constants.CODE_PERIOD) {
+ return text.substring(1);
} else {
return text;
}
@@ -1647,6 +1701,11 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
mKeyboardSwitcher.onCancelInput();
}
+ @Override
+ public void onCancelBatchInput() {
+ BatchInputUpdater.getInstance().onCancelBatchInput();
+ }
+
private void handleBackspace(final int spaceState) {
// In many cases, we may have to put the keyboard in auto-shift state again. However
// we want to wait a few milliseconds before doing it to avoid the keyboard flashing
@@ -1656,8 +1715,13 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
if (mWordComposer.isComposingWord()) {
final int length = mWordComposer.size();
if (length > 0) {
- // Immediately after a batch input.
- if (SPACE_STATE_PHANTOM == spaceState) {
+ if (mWordComposer.isBatchMode()) {
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ final String word = mWordComposer.getTypedWord();
+ ResearchLogger.latinIME_handleBackspace_batch(word, 1);
+ ResearchLogger.getInstance().uncommitCurrentLogUnit(
+ word, false /* dumpCurrentLogUnit */);
+ }
mWordComposer.reset();
} else {
mWordComposer.deleteLast();
@@ -1688,8 +1752,8 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
return;
}
if (SPACE_STATE_DOUBLE == spaceState) {
- mHandler.cancelDoubleSpacesTimer();
- if (mConnection.revertDoubleSpace()) {
+ mHandler.cancelDoubleSpacePeriodTimer();
+ if (mConnection.revertDoubleSpacePeriod()) {
// No need to reset mSpaceState, it has already be done (that's why we
// receive it as a parameter)
return;
@@ -1705,19 +1769,25 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// We should backspace one char and restart suggestion if at the end of a word.
if (mLastSelectionStart != mLastSelectionEnd) {
// If there is a selection, remove it.
- final int lengthToDelete = mLastSelectionEnd - mLastSelectionStart;
+ final int numCharsDeleted = mLastSelectionEnd - mLastSelectionStart;
mConnection.setSelection(mLastSelectionEnd, mLastSelectionEnd);
- mConnection.deleteSurroundingText(lengthToDelete, 0);
+ // Reset mLastSelectionEnd to mLastSelectionStart. This is what is supposed to
+ // happen, and if it's wrong, the next call to onUpdateSelection will correct it,
+ // but we want to set it right away to avoid it being used with the wrong values
+ // later (typically, in a subsequent press on backspace).
+ mLastSelectionEnd = mLastSelectionStart;
+ mConnection.deleteSurroundingText(numCharsDeleted, 0);
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.latinIME_handleBackspace(numCharsDeleted);
+ }
} else {
// There is no selection, just delete one character.
if (NOT_A_CURSOR_POSITION == mLastSelectionEnd) {
// This should never happen.
Log.e(TAG, "Backspace when we don't know the selection position");
}
- // 16 is android.os.Build.VERSION_CODES.JELLY_BEAN but we can't write it because
- // we want to be able to compile against the Ice Cream Sandwich SDK.
if (mTargetApplicationInfo != null
- && mTargetApplicationInfo.targetSdkVersion < 16) {
+ && mTargetApplicationInfo.targetSdkVersion < VERSION_CODES.JELLY_BEAN) {
// Backward compatibility mode. Before Jelly bean, the keyboard would simulate
// a hardware keyboard event on pressing enter or delete. This is bad for many
// reasons (there are race conditions with commits) but some applications are
@@ -1726,35 +1796,38 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
} else {
mConnection.deleteSurroundingText(1, 0);
}
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.latinIME_handleBackspace(1);
+ }
if (mDeleteCount > DELETE_ACCELERATE_AT) {
mConnection.deleteSurroundingText(1, 0);
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.latinIME_handleBackspace(1);
+ }
}
}
- if (mCurrentSettings.isSuggestionsRequested(mDisplayOrientation)) {
+ if (mSettings.getCurrent().isSuggestionsRequested(mDisplayOrientation)) {
restartSuggestionsOnWordBeforeCursorIfAtEndOfWord();
}
}
}
+ /*
+ * Strip a trailing space if necessary and returns whether it's a swap weak space situation.
+ */
private boolean maybeStripSpace(final int code,
final int spaceState, final boolean isFromSuggestionStrip) {
- if (Keyboard.CODE_ENTER == code && SPACE_STATE_SWAP_PUNCTUATION == spaceState) {
+ if (Constants.CODE_ENTER == code && SPACE_STATE_SWAP_PUNCTUATION == spaceState) {
mConnection.removeTrailingSpace();
return false;
- } else if ((SPACE_STATE_WEAK == spaceState
- || SPACE_STATE_SWAP_PUNCTUATION == spaceState)
+ }
+ if ((SPACE_STATE_WEAK == spaceState || SPACE_STATE_SWAP_PUNCTUATION == spaceState)
&& isFromSuggestionStrip) {
- if (mCurrentSettings.isWeakSpaceSwapper(code)) {
- return true;
- } else {
- if (mCurrentSettings.isWeakSpaceStripper(code)) {
- mConnection.removeTrailingSpace();
- }
- return false;
- }
- } else {
- return false;
+ if (mSettings.getCurrent().isUsuallyPrecededBySpace(code)) return false;
+ if (mSettings.getCurrent().isUsuallyFollowedBySpace(code)) return true;
+ mConnection.removeTrailingSpace();
}
+ return false;
}
private void handleCharacter(final int primaryCode, final int x,
@@ -1762,7 +1835,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
boolean isComposingWord = mWordComposer.isComposingWord();
if (SPACE_STATE_PHANTOM == spaceState &&
- !mCurrentSettings.isSymbolExcludedFromWordSeparators(primaryCode)) {
+ !mSettings.getCurrent().isWordConnector(primaryCode)) {
if (isComposingWord) {
// Sanity check
throw new RuntimeException("Should not be composing here");
@@ -1774,14 +1847,14 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// dozen milliseconds. Avoid calling it as much as possible, since we are on the UI
// thread here.
if (!isComposingWord && (isAlphabet(primaryCode)
- || mCurrentSettings.isSymbolExcludedFromWordSeparators(primaryCode))
- && mCurrentSettings.isSuggestionsRequested(mDisplayOrientation) &&
- !mConnection.isCursorTouchingWord(mCurrentSettings)) {
+ || mSettings.getCurrent().isWordConnector(primaryCode))
+ && mSettings.getCurrent().isSuggestionsRequested(mDisplayOrientation) &&
+ !mConnection.isCursorTouchingWord(mSettings.getCurrent())) {
// Reset entirely the composing state anyway, then start composing a new word unless
// the character is a single quote. The idea here is, single quote is not a
// separator and it should be treated as a normal character, except in the first
// position where it should not start composing a word.
- isComposingWord = (Keyboard.CODE_SINGLE_QUOTE != primaryCode);
+ isComposingWord = (Constants.CODE_SINGLE_QUOTE != primaryCode);
// Here we don't need to reset the last composed word. It will be reset
// when we commit this one, if we ever do; if on the other hand we backspace
// it entirely and resume suggestions on the previous word, we'd like to still
@@ -1790,15 +1863,14 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
}
if (isComposingWord) {
final int keyX, keyY;
- if (KeyboardActionListener.Adapter.isInvalidCoordinate(x)
- || KeyboardActionListener.Adapter.isInvalidCoordinate(y)) {
- keyX = x;
- keyY = y;
- } else {
+ if (Constants.isValidCoordinate(x) && Constants.isValidCoordinate(y)) {
final KeyDetector keyDetector =
mKeyboardSwitcher.getMainKeyboardView().getKeyDetector();
keyX = keyDetector.getTouchX(x);
keyY = keyDetector.getTouchY(y);
+ } else {
+ keyX = x;
+ keyY = y;
}
mWordComposer.add(primaryCode, keyX, keyY);
// If it's the first letter, make note of auto-caps state
@@ -1828,10 +1900,14 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// Returns true if we did an autocorrection, false otherwise.
private boolean handleSeparator(final int primaryCode, final int x, final int y,
final int spaceState) {
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.recordTimeForLogUnitSplit();
+ ResearchLogger.latinIME_handleSeparator(primaryCode, mWordComposer.isComposingWord());
+ }
boolean didAutoCorrect = false;
// Handle separator
if (mWordComposer.isComposingWord()) {
- if (mCurrentSettings.mCorrectionEnabled) {
+ if (mSettings.getCurrent().mCorrectionEnabled) {
// TODO: maybe cache Strings in an <String> sparse array or something
commitCurrentAutoCorrection(new String(new int[]{primaryCode}, 0, 1));
didAutoCorrect = true;
@@ -1844,31 +1920,28 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
Constants.SUGGESTION_STRIP_COORDINATE == x);
if (SPACE_STATE_PHANTOM == spaceState &&
- mCurrentSettings.isPhantomSpacePromotingSymbol(primaryCode)) {
+ mSettings.getCurrent().isUsuallyPrecededBySpace(primaryCode)) {
promotePhantomSpace();
}
sendKeyCodePoint(primaryCode);
- if (Keyboard.CODE_SPACE == primaryCode) {
- if (mCurrentSettings.isSuggestionsRequested(mDisplayOrientation)) {
- if (maybeDoubleSpace()) {
+ if (Constants.CODE_SPACE == primaryCode) {
+ if (mSettings.getCurrent().isSuggestionsRequested(mDisplayOrientation)) {
+ if (maybeDoubleSpacePeriod()) {
mSpaceState = SPACE_STATE_DOUBLE;
} else if (!isShowingPunctuationList()) {
mSpaceState = SPACE_STATE_WEAK;
}
}
- mHandler.startDoubleSpacesTimer();
- if (!mConnection.isCursorTouchingWord(mCurrentSettings)) {
- mHandler.postUpdateSuggestionStrip();
- }
+ mHandler.startDoubleSpacePeriodTimer();
+ mHandler.postUpdateSuggestionStrip();
} else {
if (swapWeakSpace) {
swapSwapperAndSpace();
mSpaceState = SPACE_STATE_SWAP_PUNCTUATION;
} else if (SPACE_STATE_PHANTOM == spaceState
- && !mCurrentSettings.isWeakSpaceStripper(primaryCode)
- && !mCurrentSettings.isPhantomSpacePromotingSymbol(primaryCode)) {
+ && mSettings.getCurrent().isUsuallyFollowedBySpace(primaryCode)) {
// If we are in phantom space state, and the user presses a separator, we want to
// stay in phantom space state so that the next keypress has a chance to add the
// space. For example, if I type "Good dat", pick "day" from the suggestion strip
@@ -1894,13 +1967,14 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
return didAutoCorrect;
}
- private CharSequence getTextWithUnderline(final CharSequence text) {
+ private CharSequence getTextWithUnderline(final String text) {
return mIsAutoCorrectionIndicatorOn
? SuggestionSpanUtils.getTextWithAutoCorrectionIndicatorUnderline(this, text)
: text;
}
private void handleClose() {
+ // TODO: Verify that words are logged properly when IME is closed.
commitTyped(LastComposedWord.NOT_A_SEPARATOR);
requestHideSelf(0);
final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView();
@@ -1911,10 +1985,10 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// TODO: make this private
// Outside LatinIME, only used by the test suite.
- /* package for tests */
+ @UsedForTesting
boolean isShowingPunctuationList() {
- if (mSuggestionStripView == null) return false;
- return mCurrentSettings.mSuggestPuncList == mSuggestionStripView.getSuggestions();
+ if (mSuggestedWords == null) return false;
+ return mSettings.getCurrent().mSuggestPuncList == mSuggestedWords;
}
private boolean isSuggestionsStripVisible() {
@@ -1922,19 +1996,20 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
return false;
if (mSuggestionStripView.isShowingAddToDictionaryHint())
return true;
- if (!mCurrentSettings.isSuggestionStripVisibleInOrientation(mDisplayOrientation))
+ if (!mSettings.getCurrent().isSuggestionStripVisibleInOrientation(mDisplayOrientation))
return false;
- if (mCurrentSettings.isApplicationSpecifiedCompletionsOn())
+ if (mSettings.getCurrent().isApplicationSpecifiedCompletionsOn())
return true;
- return mCurrentSettings.isSuggestionsRequested(mDisplayOrientation);
+ return mSettings.getCurrent().isSuggestionsRequested(mDisplayOrientation);
}
private void clearSuggestionStrip() {
- setSuggestionStrip(SuggestedWords.EMPTY, false);
+ setSuggestedWords(SuggestedWords.EMPTY, false);
setAutoCorrectionIndicator(false);
}
- private void setSuggestionStrip(final SuggestedWords words, final boolean isAutoCorrection) {
+ private void setSuggestedWords(final SuggestedWords words, final boolean isAutoCorrection) {
+ mSuggestedWords = words;
if (mSuggestionStripView != null) {
mSuggestionStripView.setSuggestions(words);
mKeyboardSwitcher.onAutoCorrectionStateChanged(isAutoCorrection);
@@ -1960,16 +2035,16 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
mHandler.cancelUpdateSuggestionStrip();
// Check if we have a suggestion engine attached.
- if (mSuggest == null || !mCurrentSettings.isSuggestionsRequested(mDisplayOrientation)) {
+ if (mSuggest == null
+ || !mSettings.getCurrent().isSuggestionsRequested(mDisplayOrientation)) {
if (mWordComposer.isComposingWord()) {
Log.w(TAG, "Called updateSuggestionsOrPredictions but suggestions were not "
+ "requested!");
- mWordComposer.setAutoCorrection(mWordComposer.getTypedWord());
}
return;
}
- if (!mWordComposer.isComposingWord() && !mCurrentSettings.mBigramPredictionEnabled) {
+ if (!mWordComposer.isComposingWord() && !mSettings.getCurrent().mBigramPredictionEnabled) {
setPunctuationSuggestions();
return;
}
@@ -1981,7 +2056,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
private SuggestedWords getSuggestedWords(final int sessionId) {
final Keyboard keyboard = mKeyboardSwitcher.getKeyboard();
- if (keyboard == null) {
+ if (keyboard == null || mSuggest == null) {
return SuggestedWords.EMPTY;
}
final String typedWord = mWordComposer.getTypedWord();
@@ -1989,16 +2064,16 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// 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.
// TODO: this is slow (2-way IPC) - we should probably cache this instead.
- final CharSequence prevWord =
- mConnection.getNthPreviousWord(mCurrentSettings.mWordSeparators,
+ final String prevWord =
+ mConnection.getNthPreviousWord(mSettings.getCurrent().mWordSeparators,
mWordComposer.isComposingWord() ? 2 : 1);
final SuggestedWords suggestedWords = mSuggest.getSuggestedWords(mWordComposer,
- prevWord, keyboard.getProximityInfo(), mCurrentSettings.mCorrectionEnabled,
+ prevWord, keyboard.getProximityInfo(), mSettings.getCurrent().mCorrectionEnabled,
sessionId);
return maybeRetrieveOlderSuggestions(typedWord, suggestedWords);
}
- private SuggestedWords maybeRetrieveOlderSuggestions(final CharSequence typedWord,
+ private SuggestedWords maybeRetrieveOlderSuggestions(final String typedWord,
final SuggestedWords suggestedWords) {
// TODO: consolidate this into getSuggestedWords
// We update the suggestion strip only when we have some suggestions to show, i.e. when
@@ -2008,45 +2083,47 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// old suggestions. Also, if we are showing the "add to dictionary" hint, we need to
// revert to suggestions - although it is unclear how we can come here if it's displayed.
if (suggestedWords.size() > 1 || typedWord.length() <= 1
- || !suggestedWords.mTypedWordValid
+ || suggestedWords.mTypedWordValid
|| mSuggestionStripView.isShowingAddToDictionaryHint()) {
return suggestedWords;
} else {
- SuggestedWords previousSuggestions = mSuggestionStripView.getSuggestions();
- if (previousSuggestions == mCurrentSettings.mSuggestPuncList) {
- previousSuggestions = SuggestedWords.EMPTY;
- }
- final ArrayList<SuggestedWords.SuggestedWordInfo> typedWordAndPreviousSuggestions =
- SuggestedWords.getTypedWordAndPreviousSuggestions(
- typedWord, previousSuggestions);
- return new SuggestedWords(typedWordAndPreviousSuggestions,
- false /* typedWordValid */,
- false /* hasAutoCorrectionCandidate */,
- false /* isPunctuationSuggestions */,
- true /* isObsoleteSuggestions */,
- false /* isPrediction */);
+ return getOlderSuggestions(typedWord);
}
}
- private void showSuggestionStrip(final SuggestedWords suggestedWords,
- final CharSequence typedWord) {
- if (null == suggestedWords || suggestedWords.size() <= 0) {
+ private SuggestedWords getOlderSuggestions(final String typedWord) {
+ SuggestedWords previousSuggestedWords = mSuggestedWords;
+ if (previousSuggestedWords == mSettings.getCurrent().mSuggestPuncList) {
+ previousSuggestedWords = SuggestedWords.EMPTY;
+ }
+ if (typedWord == null) {
+ return previousSuggestedWords;
+ }
+ final ArrayList<SuggestedWords.SuggestedWordInfo> typedWordAndPreviousSuggestions =
+ SuggestedWords.getTypedWordAndPreviousSuggestions(typedWord,
+ previousSuggestedWords);
+ return new SuggestedWords(typedWordAndPreviousSuggestions,
+ false /* typedWordValid */,
+ false /* hasAutoCorrectionCandidate */,
+ false /* isPunctuationSuggestions */,
+ true /* isObsoleteSuggestions */,
+ false /* isPrediction */);
+ }
+
+ private void showSuggestionStrip(final SuggestedWords suggestedWords, final String typedWord) {
+ if (suggestedWords.isEmpty()) {
clearSuggestionStrip();
return;
}
- final CharSequence autoCorrection;
- if (suggestedWords.size() > 0) {
- if (suggestedWords.mWillAutoCorrect) {
- autoCorrection = suggestedWords.getWord(1);
- } else {
- autoCorrection = typedWord;
- }
+ final String autoCorrection;
+ if (suggestedWords.mWillAutoCorrect) {
+ autoCorrection = suggestedWords.getWord(1);
} else {
- autoCorrection = null;
+ autoCorrection = typedWord;
}
mWordComposer.setAutoCorrection(autoCorrection);
final boolean isAutoCorrection = suggestedWords.willAutoCorrect();
- setSuggestionStrip(suggestedWords, isAutoCorrection);
+ setSuggestedWords(suggestedWords, isAutoCorrection);
setAutoCorrectionIndicator(isAutoCorrection);
setSuggestionStripShown(isSuggestionsStripVisible());
}
@@ -2056,9 +2133,9 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
if (mHandler.hasPendingUpdateSuggestions()) {
updateSuggestionStrip();
}
- final CharSequence typedAutoCorrection = mWordComposer.getAutoCorrectionOrNull();
+ final String typedAutoCorrection = mWordComposer.getAutoCorrectionOrNull();
final String typedWord = mWordComposer.getTypedWord();
- final CharSequence autoCorrection = (typedAutoCorrection != null)
+ final String autoCorrection = (typedAutoCorrection != null)
? typedAutoCorrection : typedWord;
if (autoCorrection != null) {
if (TextUtils.isEmpty(typedWord)) {
@@ -2066,8 +2143,12 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
+ "is empty? Impossible! I must commit suicide.");
}
if (ProductionFlag.IS_INTERNAL) {
- Stats.onAutoCorrection(
- typedWord, autoCorrection.toString(), separatorString, mWordComposer);
+ Stats.onAutoCorrection(typedWord, autoCorrection, separatorString, mWordComposer);
+ }
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ final SuggestedWords suggestedWords = mSuggestedWords;
+ ResearchLogger.latinIme_commitCurrentAutoCorrection(typedWord, autoCorrection,
+ separatorString, mWordComposer.isBatchMode(), suggestedWords);
}
mExpectingUpdateSelection = true;
commitChosenWord(autoCorrection, LastComposedWord.COMMIT_TYPE_DECIDED_WORD,
@@ -2089,19 +2170,20 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// Called from {@link SuggestionStripView} through the {@link SuggestionStripView#Listener}
// interface
@Override
- public void pickSuggestionManually(final int index, final CharSequence suggestion) {
- final SuggestedWords suggestedWords = mSuggestionStripView.getSuggestions();
+ public void pickSuggestionManually(final int index, final String suggestion) {
+ final SuggestedWords suggestedWords = mSuggestedWords;
// If this is a punctuation picked from the suggestion strip, pass it to onCodeInput
if (suggestion.length() == 1 && isShowingPunctuationList()) {
// Word separators are suggested before the user inputs something.
// So, LatinImeLogger logs "" as a user's input.
- LatinImeLogger.logOnManualSuggestion("", suggestion.toString(), index, suggestedWords);
+ LatinImeLogger.logOnManualSuggestion("", suggestion, index, suggestedWords);
// Rely on onCodeInput to do the complicated swapping/stripping logic consistently.
final int primaryCode = suggestion.charAt(0);
onCodeInput(primaryCode,
Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE);
if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_punctuationSuggestion(index, suggestion);
+ ResearchLogger.latinIME_punctuationSuggestion(index, suggestion,
+ false /* isBatchMode */, suggestedWords.mIsPrediction);
}
return;
}
@@ -2111,16 +2193,17 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// In the batch input mode, a manually picked suggested word should just replace
// the current batch input text and there is no need for a phantom space.
&& !mWordComposer.isBatchMode()) {
- int firstChar = Character.codePointAt(suggestion, 0);
- if ((!mCurrentSettings.isWeakSpaceStripper(firstChar))
- && (!mCurrentSettings.isWeakSpaceSwapper(firstChar))) {
+ final int firstChar = Character.codePointAt(suggestion, 0);
+ if (!mSettings.getCurrent().isWordSeparator(firstChar)
+ || mSettings.getCurrent().isUsuallyPrecededBySpace(firstChar)) {
promotePhantomSpace();
}
}
- if (mCurrentSettings.isApplicationSpecifiedCompletionsOn()
+ if (mSettings.getCurrent().isApplicationSpecifiedCompletionsOn()
&& mApplicationSpecifiedCompletions != null
&& index >= 0 && index < mApplicationSpecifiedCompletions.length) {
+ mSuggestedWords = SuggestedWords.EMPTY;
if (mSuggestionStripView != null) {
mSuggestionStripView.clear();
}
@@ -2134,14 +2217,14 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// We need to log before we commit, because the word composer will store away the user
// typed word.
- final String replacedWord = mWordComposer.getTypedWord().toString();
- LatinImeLogger.logOnManualSuggestion(replacedWord,
- suggestion.toString(), index, suggestedWords);
+ final String replacedWord = mWordComposer.getTypedWord();
+ LatinImeLogger.logOnManualSuggestion(replacedWord, suggestion, index, suggestedWords);
mExpectingUpdateSelection = true;
commitChosenWord(suggestion, LastComposedWord.COMMIT_TYPE_MANUAL_PICK,
LastComposedWord.NOT_A_SEPARATOR);
if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_pickSuggestionManually(replacedWord, index, suggestion);
+ ResearchLogger.latinIME_pickSuggestionManually(replacedWord, index, suggestion,
+ mWordComposer.isBatchMode());
}
mConnection.endBatchEdit();
// Don't allow cancellation of manual pick
@@ -2159,12 +2242,12 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
&& !AutoCorrection.isValidWord(mSuggest.getUnigramDictionaries(), suggestion, true);
if (ProductionFlag.IS_INTERNAL) {
- Stats.onSeparator((char)Keyboard.CODE_SPACE,
+ Stats.onSeparator((char)Constants.CODE_SPACE,
Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE);
}
if (showingAddToDictionaryHint && mIsUserDictionaryAvailable) {
mSuggestionStripView.showAddToDictionaryHint(
- suggestion, mCurrentSettings.mHintToSaveText);
+ suggestion, mSettings.getCurrent().mHintToSaveText);
} else {
// If we're not showing the "Touch again to save", then update the suggestion strip.
mHandler.postUpdateSuggestionStrip();
@@ -2174,58 +2257,56 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
/**
* Commits the chosen word to the text field and saves it for later retrieval.
*/
- private void commitChosenWord(final CharSequence chosenWord, final int commitType,
+ private void commitChosenWord(final String chosenWord, final int commitType,
final String separatorString) {
- final SuggestedWords suggestedWords = mSuggestionStripView.getSuggestions();
+ final SuggestedWords suggestedWords = mSuggestedWords;
mConnection.commitText(SuggestionSpanUtils.getTextWithSuggestionSpan(
this, chosenWord, suggestedWords, mIsMainDictionaryAvailable), 1);
// Add the word to the user history dictionary
- final CharSequence prevWord = addToUserHistoryDictionary(chosenWord);
+ final String prevWord = addToUserHistoryDictionary(chosenWord);
// TODO: figure out here if this is an auto-correct or if the best word is actually
// what user typed. Note: currently this is done much later in
// LastComposedWord#didCommitTypedWord by string equality of the remembered
// strings.
- mLastComposedWord = mWordComposer.commitWord(commitType, chosenWord.toString(),
- separatorString, prevWord);
+ mLastComposedWord = mWordComposer.commitWord(commitType, chosenWord, separatorString,
+ prevWord);
}
private void setPunctuationSuggestions() {
- if (mCurrentSettings.mBigramPredictionEnabled) {
+ if (mSettings.getCurrent().mBigramPredictionEnabled) {
clearSuggestionStrip();
} else {
- setSuggestionStrip(mCurrentSettings.mSuggestPuncList, false);
+ setSuggestedWords(mSettings.getCurrent().mSuggestPuncList, false);
}
setAutoCorrectionIndicator(false);
setSuggestionStripShown(isSuggestionsStripVisible());
}
- private CharSequence addToUserHistoryDictionary(final CharSequence suggestion) {
+ private String addToUserHistoryDictionary(final String suggestion) {
if (TextUtils.isEmpty(suggestion)) return null;
if (mSuggest == null) return null;
// If correction is not enabled, we don't add words to the user history dictionary.
// That's to avoid unintended additions in some sensitive fields, or fields that
// expect to receive non-words.
- if (!mCurrentSettings.mCorrectionEnabled) return null;
+ if (!mSettings.getCurrent().mCorrectionEnabled) return null;
final UserHistoryDictionary userHistoryDictionary = mUserHistoryDictionary;
if (userHistoryDictionary != null) {
- final CharSequence prevWord
- = mConnection.getNthPreviousWord(mCurrentSettings.mWordSeparators, 2);
+ final String prevWord
+ = mConnection.getNthPreviousWord(mSettings.getCurrent().mWordSeparators, 2);
final String secondWord;
if (mWordComposer.wasAutoCapitalized() && !mWordComposer.isMostlyCaps()) {
- secondWord = suggestion.toString().toLowerCase(
- mSubtypeSwitcher.getCurrentSubtypeLocale());
+ secondWord = suggestion.toLowerCase(mSubtypeSwitcher.getCurrentSubtypeLocale());
} else {
- secondWord = suggestion.toString();
+ secondWord = suggestion;
}
// We demote unrecognized words (frequency < 0, below) by specifying them as "invalid".
// We don't add words with 0-frequency (assuming they would be profanity etc.).
final int maxFreq = AutoCorrection.getMaxFrequency(
mSuggest.getUnigramDictionaries(), suggestion);
if (maxFreq == 0) return null;
- userHistoryDictionary.addToUserHistory(null == prevWord ? null : prevWord.toString(),
- secondWord, maxFreq > 0);
+ userHistoryDictionary.addToUserHistory(prevWord, secondWord, maxFreq > 0);
return prevWord;
}
return null;
@@ -2236,9 +2317,16 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
* word, else do nothing.
*/
private void restartSuggestionsOnWordBeforeCursorIfAtEndOfWord() {
- final CharSequence word = mConnection.getWordBeforeCursorIfAtEndOfWord(mCurrentSettings);
+ final CharSequence word =
+ mConnection.getWordBeforeCursorIfAtEndOfWord(mSettings.getCurrent());
if (null != word) {
restartSuggestionsOnWordBeforeCursor(word);
+ // TODO: Handle the case where the user manually moves the cursor and then backs up over
+ // a separator. In that case, the current log unit should not be uncommitted.
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.getInstance().uncommitCurrentLogUnit(word.toString(),
+ true /* dumpCurrentLogUnit */);
+ }
}
}
@@ -2251,9 +2339,9 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
}
private void revertCommit() {
- final CharSequence previousWord = mLastComposedWord.mPrevWord;
+ final String previousWord = mLastComposedWord.mPrevWord;
final String originallyTypedWord = mLastComposedWord.mTypedWord;
- final CharSequence committedWord = mLastComposedWord.mCommittedWord;
+ final String committedWord = mLastComposedWord.mCommittedWord;
final int cancelLength = committedWord.length();
final int separatorLength = LastComposedWord.getSeparatorLength(
mLastComposedWord.mSeparatorString);
@@ -2263,9 +2351,9 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
if (mWordComposer.isComposingWord()) {
throw new RuntimeException("revertCommit, but we are composing a word");
}
- final String wordBeforeCursor =
+ final CharSequence wordBeforeCursor =
mConnection.getTextBeforeCursor(deleteLength, 0)
- .subSequence(0, cancelLength).toString();
+ .subSequence(0, cancelLength);
if (!TextUtils.equals(committedWord, wordBeforeCursor)) {
throw new RuntimeException("revertCommit check failed: we thought we were "
+ "reverting \"" + committedWord
@@ -2274,8 +2362,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
}
mConnection.deleteSurroundingText(deleteLength, 0);
if (!TextUtils.isEmpty(previousWord) && !TextUtils.isEmpty(committedWord)) {
- mUserHistoryDictionary.cancelAddingUserHistory(
- previousWord.toString(), committedWord.toString());
+ mUserHistoryDictionary.cancelAddingUserHistory(previousWord, committedWord);
}
mConnection.commitText(originallyTypedWord + mLastComposedWord.mSeparatorString, 1);
if (ProductionFlag.IS_INTERNAL) {
@@ -2283,7 +2370,10 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE);
}
if (ProductionFlag.IS_EXPERIMENTAL) {
- ResearchLogger.latinIME_revertCommit(originallyTypedWord);
+ ResearchLogger.latinIME_revertCommit(committedWord, originallyTypedWord,
+ mWordComposer.isBatchMode(), mLastComposedWord.mSeparatorString);
+ ResearchLogger.getInstance().uncommitCurrentLogUnit(committedWord,
+ true /* dumpCurrentLogUnit */);
}
// Don't restart suggestion yet. We'll restart if the user deletes the
// separator.
@@ -2294,19 +2384,22 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// This essentially inserts a space, and that's it.
public void promotePhantomSpace() {
- if (mCurrentSettings.shouldInsertSpacesAutomatically()) {
- sendKeyCodePoint(Keyboard.CODE_SPACE);
+ if (mSettings.getCurrent().shouldInsertSpacesAutomatically()) {
+ sendKeyCodePoint(Constants.CODE_SPACE);
+ if (ProductionFlag.IS_EXPERIMENTAL) {
+ ResearchLogger.latinIME_promotePhantomSpace();
+ }
}
}
// Used by the RingCharBuffer
public boolean isWordSeparator(final int code) {
- return mCurrentSettings.isWordSeparator(code);
+ return mSettings.getCurrent().isWordSeparator(code);
}
// TODO: Make this private
// Outside LatinIME, only used by the {@link InputTestsBase} test suite.
- /* package for test */
+ @UsedForTesting
void loadKeyboard() {
// When the device locale is changed in SetupWizard etc., this method may get called via
// onConfigurationChanged before SoftInputWindow is shown.
@@ -2314,7 +2407,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
loadSettings();
if (mKeyboardSwitcher.getMainKeyboardView() != null) {
// Reload keyboard because the current language has been changed.
- mKeyboardSwitcher.loadKeyboard(getCurrentInputEditorInfo(), mCurrentSettings);
+ mKeyboardSwitcher.loadKeyboard(getCurrentInputEditorInfo(), mSettings.getCurrent());
}
// Since we just changed languages, we should re-evaluate suggestions with whatever word
// we are currently composing. If we are not composing anything, we may want to display
@@ -2322,13 +2415,6 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
mHandler.postUpdateSuggestionStrip();
}
- // TODO: Remove this method from {@link LatinIME} and move {@link FeedbackManager} to
- // {@link KeyboardSwitcher}. Called from KeyboardSwitcher
- public void hapticAndAudioFeedback(final int primaryCode) {
- mFeedbackManager.hapticAndAudioFeedback(
- primaryCode, mKeyboardSwitcher.getMainKeyboardView());
- }
-
// Callback called by PointerTracker through the KeyboardActionListener. This is called when a
// key is depressed; release matching call is onReleaseKey below.
@Override
@@ -2345,16 +2431,16 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
// If accessibility is on, ensure the user receives keyboard state updates.
if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
switch (primaryCode) {
- case Keyboard.CODE_SHIFT:
+ case Constants.CODE_SHIFT:
AccessibleKeyboardViewProxy.getInstance().notifyShiftState();
break;
- case Keyboard.CODE_SWITCH_ALPHA_SYMBOL:
+ case Constants.CODE_SWITCH_ALPHA_SYMBOL:
AccessibleKeyboardViewProxy.getInstance().notifySymbolsState();
break;
}
}
- if (Keyboard.CODE_DELETE == primaryCode) {
+ if (Constants.CODE_DELETE == primaryCode) {
// This is a stopgap solution to avoid leaving a high surrogate alone in a text view.
// In the future, we need to deprecate deteleSurroundingText() and have a surrogate
// pair-friendly way of deleting characters in InputConnection.
@@ -2366,6 +2452,35 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
}
}
+ // Hooks for hardware keyboard
+ @Override
+ public boolean onKeyDown(final int keyCode, final KeyEvent event) {
+ if (!ProductionFlag.IS_HARDWARE_KEYBOARD_SUPPORTED) return super.onKeyDown(keyCode, event);
+ // onHardwareKeyEvent, like onKeyDown returns true if it handled the event, false if
+ // it doesn't know what to do with it and leave it to the application. For example,
+ // hardware key events for adjusting the screen's brightness are passed as is.
+ if (mEventInterpreter.onHardwareKeyEvent(event)) {
+ final long keyIdentifier = event.getDeviceId() << 32 + event.getKeyCode();
+ mCurrentlyPressedHardwareKeys.add(keyIdentifier);
+ return true;
+ }
+ return super.onKeyDown(keyCode, event);
+ }
+
+ @Override
+ public boolean onKeyUp(final int keyCode, final KeyEvent event) {
+ final long keyIdentifier = event.getDeviceId() << 32 + event.getKeyCode();
+ if (mCurrentlyPressedHardwareKeys.remove(keyIdentifier)) {
+ return true;
+ }
+ return super.onKeyUp(keyCode, event);
+ }
+
+ // onKeyDown and onKeyUp are the main events we are interested in. There are two more events
+ // related to handling of hardware key events that we may want to implement in the future:
+ // boolean onKeyLongPress(final int keyCode, final KeyEvent event);
+ // boolean onKeyMultiple(final int keyCode, final int count, final KeyEvent event);
+
// receive ringer mode change and network state change.
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
@@ -2374,7 +2489,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
mSubtypeSwitcher.onNetworkStateChanged(intent);
} else if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {
- mFeedbackManager.onRingerModeChanged();
+ mKeyboardSwitcher.onRingerModeChanged();
}
}
};
@@ -2400,7 +2515,9 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
private void launchSubActivity(final Class<? extends Activity> activityClass) {
Intent intent = new Intent();
intent.setClass(LatinIME.this, activityClass);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
+ | Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
@@ -2411,15 +2528,14 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
getString(R.string.language_selection_title),
getString(R.string.english_ime_settings),
};
- final Context context = this;
final DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface di, int position) {
di.dismiss();
switch (position) {
case 0:
- Intent intent = CompatUtils.getInputLanguageSelectionIntent(
- ImfUtils.getInputMethodIdOfThisIme(context),
+ final Intent intent = IntentUtils.getInputLanguageSelectionIntent(
+ mRichImm.getInputMethodIdOfThisIme(),
Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
@@ -2457,13 +2573,19 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
dialog.show();
}
+ // TODO: can this be removed somehow without breaking the tests?
+ @UsedForTesting
+ /* package for test */ String getFirstSuggestedWord() {
+ return mSuggestedWords.size() > 0 ? mSuggestedWords.getWord(0) : null;
+ }
+
public void debugDumpStateAndCrashWithException(final String context) {
final StringBuilder s = new StringBuilder();
s.append("Target application : ").append(mTargetApplicationInfo.name)
.append("\nPackage : ").append(mTargetApplicationInfo.packageName)
.append("\nTarget app sdk version : ")
.append(mTargetApplicationInfo.targetSdkVersion)
- .append("\nAttributes : ").append(mCurrentSettings.getInputAttributesDebugString())
+ .append("\nAttributes : ").append(mSettings.getCurrent().mInputAttributes)
.append("\nContext : ").append(context);
throw new RuntimeException(s.toString());
}
@@ -2477,13 +2599,14 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
final Keyboard keyboard = mKeyboardSwitcher.getKeyboard();
final int keyboardMode = keyboard != null ? keyboard.mId.mMode : -1;
p.println(" Keyboard mode = " + keyboardMode);
+ final SettingsValues settingsValues = mSettings.getCurrent();
p.println(" mIsSuggestionsSuggestionsRequested = "
- + mCurrentSettings.isSuggestionsRequested(mDisplayOrientation));
- p.println(" mCorrectionEnabled=" + mCurrentSettings.mCorrectionEnabled);
+ + settingsValues.isSuggestionsRequested(mDisplayOrientation));
+ p.println(" mCorrectionEnabled=" + settingsValues.mCorrectionEnabled);
p.println(" isComposingWord=" + mWordComposer.isComposingWord());
- p.println(" mSoundOn=" + mCurrentSettings.mSoundOn);
- p.println(" mVibrateOn=" + mCurrentSettings.mVibrateOn);
- p.println(" mKeyPreviewPopupOn=" + mCurrentSettings.mKeyPreviewPopupOn);
- p.println(" inputAttributes=" + mCurrentSettings.getInputAttributesDebugString());
+ p.println(" mSoundOn=" + settingsValues.mSoundOn);
+ p.println(" mVibrateOn=" + settingsValues.mVibrateOn);
+ p.println(" mKeyPreviewPopupOn=" + settingsValues.mKeyPreviewPopupOn);
+ p.println(" inputAttributes=" + settingsValues.mInputAttributes);
}
}