aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/event/InputTransaction.java48
-rw-r--r--java/src/com/android/inputmethod/keyboard/MainKeyboardView.java4
-rw-r--r--java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java4
-rw-r--r--java/src/com/android/inputmethod/keyboard/MoreKeysPanel.java10
-rw-r--r--java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java20
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java128
-rw-r--r--java/src/com/android/inputmethod/latin/RichInputMethodManager.java73
-rw-r--r--java/src/com/android/inputmethod/latin/Suggest.java1
-rw-r--r--java/src/com/android/inputmethod/latin/SuggestedWords.java33
-rw-r--r--java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java187
-rw-r--r--java/src/com/android/inputmethod/latin/settings/DebugSettings.java2
-rw-r--r--java/src/com/android/inputmethod/latin/settings/SettingsValues.java5
-rw-r--r--java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java15
-rw-r--r--java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java2
14 files changed, 299 insertions, 233 deletions
diff --git a/java/src/com/android/inputmethod/event/InputTransaction.java b/java/src/com/android/inputmethod/event/InputTransaction.java
new file mode 100644
index 000000000..5e046a80e
--- /dev/null
+++ b/java/src/com/android/inputmethod/event/InputTransaction.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.event;
+
+/**
+ * An object encapsulating a single transaction for input.
+ */
+public class InputTransaction {
+ // UPDATE_LATER is stronger than UPDATE_NOW. The reason for this is, if we have to update later,
+ // it's because something will change that we can't evaluate now, which means that even if we
+ // re-evaluate now we'll have to do it again later. The only case where that wouldn't apply
+ // would be if we needed to update now to find out the new state right away, but then we
+ // can't do it with this deferred mechanism anyway.
+ public static final int SHIFT_NO_UPDATE = 0;
+ public static final int SHIFT_UPDATE_NOW = 1;
+ public static final int SHIFT_UPDATE_LATER = 2;
+
+ // Initial conditions
+ public final int mShiftState;
+
+ // Outputs
+ private int mRequiredShiftUpdate = SHIFT_NO_UPDATE;
+
+ public InputTransaction(final int shiftState) {
+ mShiftState = shiftState;
+ }
+
+ public void requireShiftUpdate(final int updateType) {
+ mRequiredShiftUpdate = Math.max(mRequiredShiftUpdate, updateType);
+ }
+ public int getRequiredShiftUpdate() {
+ return mRequiredShiftUpdate;
+ }
+}
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index 6c56b8aab..3590c486b 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -700,12 +700,12 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
}
@Override
- public void onCancelMoreKeysPanel(final MoreKeysPanel panel) {
+ public void onCancelMoreKeysPanel() {
PointerTracker.dismissAllMoreKeysPanels();
}
@Override
- public void onDismissMoreKeysPanel(final MoreKeysPanel panel) {
+ public void onDismissMoreKeysPanel() {
dimEntireKeyboard(false /* dimmed */);
if (isShowingMoreKeysPanel()) {
mMoreKeysPanel.removeFromParent();
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
index 1891dfc74..fc331970b 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java
@@ -122,7 +122,7 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel
onMoveKeyInternal(x, y, pointerId);
if (hasOldKey && mCurrentKey == null) {
// If the pointer has moved too far away from any target then cancel the panel.
- mController.onCancelMoreKeysPanel(this);
+ mController.onCancelMoreKeysPanel();
}
}
@@ -184,7 +184,7 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel
if (!isShowingInParent()) {
return;
}
- mController.onDismissMoreKeysPanel(this);
+ mController.onDismissMoreKeysPanel();
}
@Override
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysPanel.java b/java/src/com/android/inputmethod/keyboard/MoreKeysPanel.java
index 4a33e6536..7bddd09f6 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysPanel.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysPanel.java
@@ -29,24 +29,22 @@ public interface MoreKeysPanel {
/**
* Remove the current {@link MoreKeysPanel} from the target view.
- * @param panel the panel to be dismissed.
*/
- public void onDismissMoreKeysPanel(final MoreKeysPanel panel);
+ public void onDismissMoreKeysPanel();
/**
* Instructs the parent to cancel the panel (e.g., when entering a different input mode).
- * @param panel the panel to be canceled.
*/
- public void onCancelMoreKeysPanel(final MoreKeysPanel panel);
+ public void onCancelMoreKeysPanel();
}
public static final Controller EMPTY_CONTROLLER = new Controller() {
@Override
public void onShowMoreKeysPanel(final MoreKeysPanel panel) {}
@Override
- public void onDismissMoreKeysPanel(final MoreKeysPanel panel) {}
+ public void onDismissMoreKeysPanel() {}
@Override
- public void onCancelMoreKeysPanel(final MoreKeysPanel panel) {}
+ public void onCancelMoreKeysPanel() {}
};
/**
diff --git a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java
index cd18a6ba5..d6178fcee 100644
--- a/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java
+++ b/java/src/com/android/inputmethod/latin/DictionaryFacilitatorForSuggest.java
@@ -55,7 +55,6 @@ public class DictionaryFacilitatorForSuggest {
private final ConcurrentHashMap<String, Dictionary> mDictionaries =
CollectionUtils.newConcurrentHashMap();
- private HashSet<String> mDictionarySubsetForDebug = null;
private Dictionary mMainDictionary;
private ContactsBinaryDictionary mContactsDictionary;
@@ -85,7 +84,6 @@ public class DictionaryFacilitatorForSuggest {
mContext = context;
mLocale = locale;
mLatchForWaitingLoadingMainDictionary = new CountDownLatch(1);
- initForDebug(settingsValues);
loadMainDict(context, locale, listener);
setUserDictionary(new UserBinaryDictionary(context, locale));
resetAdditionalDictionaries(oldDictionaryFacilitator, settingsValues);
@@ -101,7 +99,6 @@ public class DictionaryFacilitatorForSuggest {
final DictionaryFacilitatorForSuggest oldDictionaryFacilitator) {
mContext = oldDictionaryFacilitator.mContext;
mLocale = oldDictionaryFacilitator.mLocale;
- mDictionarySubsetForDebug = oldDictionaryFacilitator.mDictionarySubsetForDebug;
mLatchForWaitingLoadingMainDictionary = new CountDownLatch(1);
loadMainDict(mContext, mLocale, listener);
// Transfer user dictionary.
@@ -130,7 +127,6 @@ public class DictionaryFacilitatorForSuggest {
mContext = oldDictionaryFacilitator.mContext;
mLocale = oldDictionaryFacilitator.mLocale;
mLatchForWaitingLoadingMainDictionary = new CountDownLatch(0);
- initForDebug(settingsValues);
// Transfer main dictionary.
setMainDictionary(oldDictionaryFacilitator.mMainDictionary);
oldDictionaryFacilitator.removeDictionary(Dictionary.TYPE_MAIN);
@@ -197,12 +193,12 @@ public class DictionaryFacilitatorForSuggest {
}
}
- // initialize a debug flag for the personalization
- private void initForDebug(final SettingsValues settingsValues) {
- if (settingsValues.mUseOnlyPersonalizationDictionaryForDebug) {
- mDictionarySubsetForDebug = new HashSet<String>();
- mDictionarySubsetForDebug.add(Dictionary.TYPE_PERSONALIZATION);
- }
+ public boolean needsToBeRecreated(final Locale newLocale,
+ final SettingsValues newSettingsValues) {
+ return !mLocale.equals(newLocale)
+ || (newSettingsValues.mUseContactsDict != (mContactsDictionary != null))
+ || (newSettingsValues.mUsePersonalizedDicts != (mUserHistoryDictionary != null))
+ || (newSettingsValues.mUsePersonalizedDicts != hasPersonalizationDictionary());
}
public void close() {
@@ -531,10 +527,6 @@ public class DictionaryFacilitatorForSuggest {
}
private void addOrReplaceDictionary(final String key, final Dictionary dict) {
- if (mDictionarySubsetForDebug != null && !mDictionarySubsetForDebug.contains(key)) {
- Log.w(TAG, "Ignore add " + key + " dictionary for debug.");
- return;
- }
final Dictionary oldDict;
if (dict == null) {
oldDict = mDictionaries.remove(key);
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index bfc578082..44353ba06 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -78,7 +78,6 @@ import com.android.inputmethod.latin.suggestions.SuggestionStripView;
import com.android.inputmethod.latin.suggestions.SuggestionStripViewAccessor;
import com.android.inputmethod.latin.utils.ApplicationUtils;
import com.android.inputmethod.latin.utils.CapsModeUtils;
-import com.android.inputmethod.latin.utils.CompletionInfoUtils;
import com.android.inputmethod.latin.utils.CoordinateUtils;
import com.android.inputmethod.latin.utils.ImportantNoticeUtils;
import com.android.inputmethod.latin.utils.IntentUtils;
@@ -124,9 +123,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
private View mKeyPreviewBackingView;
private SuggestionStripView mSuggestionStripView;
- // TODO[IL]: remove this member completely.
- public CompletionInfo[] mApplicationSpecifiedCompletions;
-
private RichInputMethodManager mRichImm;
@UsedForTesting final KeyboardSwitcher mKeyboardSwitcher;
private final SubtypeSwitcher mSubtypeSwitcher;
@@ -192,8 +188,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final KeyboardSwitcher switcher = latinIme.mKeyboardSwitcher;
switch (msg.what) {
case MSG_UPDATE_SUGGESTION_STRIP:
+ cancelUpdateSuggestionStrip();
latinIme.mInputLogic.performUpdateSuggestionStripSync(
- latinIme.mSettings.getCurrent(), this /* handler */);
+ latinIme.mSettings.getCurrent());
break;
case MSG_UPDATE_SHIFT_STATE:
switcher.updateShiftState();
@@ -530,27 +527,31 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final EditorInfo editorInfo = getCurrentInputEditorInfo();
final InputAttributes inputAttributes = new InputAttributes(editorInfo, isFullscreenMode());
mSettings.loadSettings(this, locale, inputAttributes);
- AudioAndHapticFeedbackManager.getInstance().onSettingsChanged(mSettings.getCurrent());
- // To load the keyboard we need to load all the settings once, but resetting the
- // contacts dictionary should be deferred until after the new layout has been displayed
- // to improve responsivity. In the language switching process, we post a reopenDictionaries
- // message, then come here to read the settings for the new language before we change
- // the layout; at this time, we need to skip resetting the contacts dictionary. It will
- // be done later inside {@see #initSuggest()} when the reopenDictionaries message is
- // processed.
final SettingsValues currentSettingsValues = mSettings.getCurrent();
- final Suggest suggest = mInputLogic.mSuggest;
- if (!mHandler.hasPendingReopenDictionaries() && suggest != null) {
+ AudioAndHapticFeedbackManager.getInstance().onSettingsChanged(currentSettingsValues);
+ // This method is called on startup and language switch, before the new layout has
+ // been displayed. Opening dictionaries never affects responsivity as dictionaries are
+ // asynchronously loaded.
+ initOrResetSuggestForSettingsValues(mInputLogic.mSuggest, locale, currentSettingsValues);
+ }
+
+ private void initOrResetSuggestForSettingsValues(final Suggest oldSuggest,
+ final Locale locale, final SettingsValues settingsValues) {
+ if (!mHandler.hasPendingReopenDictionaries() && oldSuggest != null) {
// May need to reset dictionaries depending on the user settings.
final DictionaryFacilitatorForSuggest oldDictionaryFacilitator =
- suggest.mDictionaryFacilitator;
+ oldSuggest.mDictionaryFacilitator;
+ if (!oldDictionaryFacilitator.needsToBeRecreated(locale, settingsValues)) {
+ // Continue to use the same dictionary facilitator if no configuration has changed.
+ refreshPersonalizationDictionarySession();
+ return;
+ }
final DictionaryFacilitatorForSuggest dictionaryFacilitator =
- new DictionaryFacilitatorForSuggest(currentSettingsValues,
- oldDictionaryFacilitator);
+ new DictionaryFacilitatorForSuggest(settingsValues, oldDictionaryFacilitator);
// Create Suggest instance with the new dictionary facilitator.
- resetSuggest(new Suggest(suggest /* oldSuggest */, dictionaryFacilitator));
- } else if (suggest == null) {
- initSuggestForLocale(locale);
+ replaceSuggest(new Suggest(oldSuggest, dictionaryFacilitator));
+ } else if (oldSuggest == null) {
+ initSuggest();
}
}
@@ -610,13 +611,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
} else {
subtypeLocale = switcherSubtypeLocale;
}
- initSuggestForLocale(subtypeLocale);
+ initSuggestForLocale(mInputLogic.mSuggest, subtypeLocale);
}
- private void initSuggestForLocale(final Locale locale) {
+ private void initSuggestForLocale(final Suggest oldSuggest, final Locale locale) {
final SettingsValues settingsValues = mSettings.getCurrent();
final DictionaryFacilitatorForSuggest oldDictionaryFacilitator =
- (mInputLogic.mSuggest == null) ? null : mInputLogic.mSuggest.mDictionaryFacilitator;
+ (oldSuggest == null) ? null : oldSuggest.mDictionaryFacilitator;
// Creates new dictionary facilitator for the new locale.
final DictionaryFacilitatorForSuggest dictionaryFacilitator =
new DictionaryFacilitatorForSuggest(this /* context */, locale, settingsValues,
@@ -625,7 +626,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (settingsValues.mCorrectionEnabled) {
newSuggest.setAutoCorrectionThreshold(settingsValues.mAutoCorrectionThreshold);
}
- resetSuggest(newSuggest);
+ replaceSuggest(newSuggest);
}
/* package private */ void resetSuggestMainDict() {
@@ -633,10 +634,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mInputLogic.mSuggest.mDictionaryFacilitator;
final DictionaryFacilitatorForSuggest dictionaryFacilitator =
new DictionaryFacilitatorForSuggest(this /* listener */, oldDictionaryFacilitator);
- resetSuggest(new Suggest(mInputLogic.mSuggest /* oldSuggest */, dictionaryFacilitator));
+ replaceSuggest(new Suggest(mInputLogic.mSuggest /* oldSuggest */, dictionaryFacilitator));
}
- private void resetSuggest(final Suggest newSuggest) {
+ private void replaceSuggest(final Suggest newSuggest) {
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
ResearchLogger.getInstance().initDictionary(newSuggest.mDictionaryFacilitator);
}
@@ -808,7 +809,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// The EditorInfo might have a flag that affects fullscreen mode.
// Note: This call should be done by InputMethodService?
updateFullscreenMode();
- mApplicationSpecifiedCompletions = null;
// The app calling setText() has the effect of clearing the composing
// span, so we should reset our state unconditionally, even if restarting is true.
@@ -875,7 +875,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
// This will set the punctuation suggestions if next word suggestion is off;
// otherwise it will clear the suggestion strip.
- setNeutralSuggestionStripInternal();
+ setNeutralSuggestionStrip();
mHandler.cancelUpdateSuggestionStrip();
mHandler.cancelDoubleSpacePeriodTimer();
@@ -950,8 +950,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// NOTE: the test harness subclasses LatinIME and overrides isInputViewShown().
// TODO: find a better way to simulate actual execution.
if (isInputViewShown() &&
- mInputLogic.onUpdateSelection(mSettings.getCurrent(), oldSelStart, oldSelEnd,
- newSelStart, newSelEnd, composingSpanStart, composingSpanEnd)) {
+ mInputLogic.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd)) {
mKeyboardSwitcher.updateShiftState();
}
@@ -1030,8 +1029,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
return;
}
- mApplicationSpecifiedCompletions =
- CompletionInfoUtils.removeNulls(applicationSpecifiedCompletions);
final ArrayList<SuggestedWords.SuggestedWordInfo> applicationSuggestedWords =
SuggestedWords.getFromApplicationSpecifiedCompletions(
@@ -1046,18 +1043,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
}
- private void setSuggestionStripShownInternal(final boolean isSuggestionStripVisible) {
- // TODO: Modify this if we support suggestions with hard keyboard
- if (!onEvaluateInputViewShown() || !hasSuggestionStripView()) {
- return;
- }
- if (isSuggestionStripVisible) {
- mSuggestionStripView.setVisibility(View.VISIBLE);
- } else {
- mSuggestionStripView.setVisibility(isFullscreenMode() ? View.GONE : View.INVISIBLE);
- }
- }
-
private int getAdjustedBackingViewHeight() {
final int currentHeight = mKeyPreviewBackingView.getHeight();
if (currentHeight > 0) {
@@ -1295,7 +1280,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@Override
public void onStartBatchInput() {
- mInputLogic.onStartBatchInput(mSettings.getCurrent(), mKeyboardSwitcher, mHandler);
+ mInputLogic.onStartBatchInput(mSettings.getCurrent(), mKeyboardSwitcher, mHandler);
}
@Override
@@ -1305,7 +1290,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@Override
public void onEndBatchInput(final InputPointers batchPointers) {
- mInputLogic.onEndBatchInput(mSettings.getCurrent(), batchPointers);
+ mInputLogic.onEndBatchInput(batchPointers);
}
@Override
@@ -1383,13 +1368,23 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
public void setSuggestedWords(final SuggestedWords suggestedWords,
final boolean isSuggestionStripVisible) {
mInputLogic.setSuggestedWords(suggestedWords);
+ // TODO: Modify this when we support suggestions with hard keyboard
if (!hasSuggestionStripView()) {
return;
}
+ mKeyboardSwitcher.onAutoCorrectionStateChanged(suggestedWords.mWillAutoCorrect);
+ if (!onEvaluateInputViewShown()) {
+ return;
+ }
+ if (!isSuggestionStripVisible) {
+ mSuggestionStripView.setVisibility(isFullscreenMode() ? View.GONE : View.INVISIBLE);
+ return;
+ }
+ mSuggestionStripView.setVisibility(View.VISIBLE);
+
final SettingsValues currentSettings = mSettings.getCurrent();
final boolean showSuggestions;
- if (SuggestedWords.EMPTY == suggestedWords
- || suggestedWords.isPunctuationSuggestions()
+ if (SuggestedWords.EMPTY == suggestedWords || suggestedWords.isPunctuationSuggestions()
|| !currentSettings.isSuggestionsRequested()) {
showSuggestions = !mSuggestionStripView.maybeShowImportantNoticeTitle(
currentSettings.mInputAttributes);
@@ -1400,8 +1395,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mSuggestionStripView.setSuggestions(suggestedWords,
SubtypeLocaleUtils.isRtlLanguage(mSubtypeSwitcher.getCurrentSubtype()));
}
- mKeyboardSwitcher.onAutoCorrectionStateChanged(suggestedWords.mWillAutoCorrect);
- setSuggestionStripShownInternal(isSuggestionStripVisible);
}
// TODO[IL]: Move this out of LatinIME.
@@ -1445,32 +1438,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
sequenceNumber, callback);
}
- // TODO[IL]: Move this to InputLogic
- public SuggestedWords maybeRetrieveOlderSuggestions(final String typedWord,
- final SuggestedWords suggestedWords, final SuggestedWords previousSuggestedWords) {
- // TODO: consolidate this into getSuggestedWords
- // We update the suggestion strip only when we have some suggestions to show, i.e. when
- // the suggestion count is > 1; else, we leave the old suggestions, with the typed word
- // replaced with the new one. However, when the length of the typed word is 1 or 0 (after
- // a deletion typically), we do want to remove the 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
- || !hasSuggestionStripView() || isShowingAddToDictionaryHint()) {
- return suggestedWords;
- } else {
- final SuggestedWords punctuationList =
- mSettings.getCurrent().mSpacingAndPunctuations.mSuggestPuncList;
- final SuggestedWords oldSuggestedWords = previousSuggestedWords == punctuationList
- ? SuggestedWords.EMPTY : previousSuggestedWords;
- final ArrayList<SuggestedWords.SuggestedWordInfo> typedWordAndPreviousSuggestions =
- SuggestedWords.getTypedWordAndPreviousSuggestions(typedWord, oldSuggestedWords);
- return new SuggestedWords(typedWordAndPreviousSuggestions, null /* rawSuggestions */,
- false /* typedWordValid */, false /* hasAutoCorrectionCandidate */,
- true /* isObsoleteSuggestions */, false /* isPrediction */);
- }
- }
-
@Override
public void showSuggestionStrip(final SuggestedWords sourceSuggestedWords) {
final SuggestedWords suggestedWords =
@@ -1511,15 +1478,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
mSuggestionStripView.showAddToDictionaryHint(word);
}
- // TODO[IL]: Define a clean interface for this
// This will show either an empty suggestion strip (if prediction is enabled) or
// punctuation suggestions (if it's disabled).
@Override
public void setNeutralSuggestionStrip() {
- setNeutralSuggestionStripInternal();
- }
-
- private void setNeutralSuggestionStripInternal() {
final SettingsValues currentSettings = mSettings.getCurrent();
final SuggestedWords neutralSuggestions = currentSettings.mBigramPredictionEnabled
? SuggestedWords.EMPTY : currentSettings.mSpacingAndPunctuations.mSuggestPuncList;
@@ -1733,7 +1695,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final DictionaryFacilitatorForSuggest dictionaryFacilitator =
new DictionaryFacilitatorForSuggest(this, locale, mSettings.getCurrent(),
this /* listener */, oldDictionaryFacilitator);
- resetSuggest(new Suggest(locale, dictionaryFacilitator));
+ replaceSuggest(new Suggest(locale, dictionaryFacilitator));
}
// DO NOT USE THIS for any other purpose than testing.
diff --git a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
index 6b6bbf3a7..630a03670 100644
--- a/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
+++ b/java/src/com/android/inputmethod/latin/RichInputMethodManager.java
@@ -50,7 +50,7 @@ public final class RichInputMethodManager {
private static final RichInputMethodManager sInstance = new RichInputMethodManager();
private InputMethodManagerCompatWrapper mImmWrapper;
- private InputMethodInfo mInputMethodInfoOfThisIme;
+ private InputMethodInfoCache mInputMethodInfoCache;
final HashMap<InputMethodInfo, List<InputMethodSubtype>>
mSubtypeListCacheWithImplicitlySelectedSubtypes = CollectionUtils.newHashMap();
final HashMap<InputMethodInfo, List<InputMethodSubtype>>
@@ -83,7 +83,8 @@ public final class RichInputMethodManager {
return;
}
mImmWrapper = new InputMethodManagerCompatWrapper(context);
- mInputMethodInfoOfThisIme = getInputMethodInfoOfThisIme(context);
+ mInputMethodInfoCache = new InputMethodInfoCache(
+ mImmWrapper.mImm, context.getPackageName());
// Initialize additional subtypes.
SubtypeLocaleUtils.init(context);
@@ -99,20 +100,10 @@ public final class RichInputMethodManager {
return mImmWrapper.mImm;
}
- private InputMethodInfo getInputMethodInfoOfThisIme(final Context context) {
- final String packageName = context.getPackageName();
- for (final InputMethodInfo imi : mImmWrapper.mImm.getInputMethodList()) {
- if (imi.getPackageName().equals(packageName)) {
- return imi;
- }
- }
- throw new RuntimeException("Input method id for " + packageName + " not found.");
- }
-
public List<InputMethodSubtype> getMyEnabledInputMethodSubtypeList(
boolean allowsImplicitlySelectedSubtypes) {
- return getEnabledInputMethodSubtypeList(mInputMethodInfoOfThisIme,
- allowsImplicitlySelectedSubtypes);
+ return getEnabledInputMethodSubtypeList(
+ getInputMethodInfoOfThisIme(), allowsImplicitlySelectedSubtypes);
}
public boolean switchToNextInputMethod(final IBinder token, final boolean onlyCurrentIme) {
@@ -153,10 +144,10 @@ public final class RichInputMethodManager {
private boolean switchToNextInputMethodAndSubtype(final IBinder token) {
final InputMethodManager imm = mImmWrapper.mImm;
final List<InputMethodInfo> enabledImis = imm.getEnabledInputMethodList();
- final int currentIndex = getImiIndexInList(mInputMethodInfoOfThisIme, enabledImis);
+ final int currentIndex = getImiIndexInList(getInputMethodInfoOfThisIme(), enabledImis);
if (currentIndex == INDEX_NOT_FOUND) {
Log.w(TAG, "Can't find current IME in enabled IMEs: IME package="
- + mInputMethodInfoOfThisIme.getPackageName());
+ + getInputMethodInfoOfThisIme().getPackageName());
return false;
}
final InputMethodInfo nextImi = getNextNonAuxiliaryIme(currentIndex, enabledImis);
@@ -213,16 +204,45 @@ public final class RichInputMethodManager {
return true;
}
+ private static class InputMethodInfoCache {
+ private final InputMethodManager mImm;
+ private final String mImePackageName;
+
+ private InputMethodInfo mCachedValue;
+
+ public InputMethodInfoCache(final InputMethodManager imm, final String imePackageName) {
+ mImm = imm;
+ mImePackageName = imePackageName;
+ }
+
+ public synchronized InputMethodInfo get() {
+ if (mCachedValue != null) {
+ return mCachedValue;
+ }
+ for (final InputMethodInfo imi : mImm.getInputMethodList()) {
+ if (imi.getPackageName().equals(mImePackageName)) {
+ mCachedValue = imi;
+ return imi;
+ }
+ }
+ throw new RuntimeException("Input method id for " + mImePackageName + " not found.");
+ }
+
+ public synchronized void clear() {
+ mCachedValue = null;
+ }
+ }
+
public InputMethodInfo getInputMethodInfoOfThisIme() {
- return mInputMethodInfoOfThisIme;
+ return mInputMethodInfoCache.get();
}
public String getInputMethodIdOfThisIme() {
- return mInputMethodInfoOfThisIme.getId();
+ return getInputMethodInfoOfThisIme().getId();
}
public boolean checkIfSubtypeBelongsToThisImeAndEnabled(final InputMethodSubtype subtype) {
- return checkIfSubtypeBelongsToImeAndEnabled(mInputMethodInfoOfThisIme, subtype);
+ return checkIfSubtypeBelongsToImeAndEnabled(getInputMethodInfoOfThisIme(), subtype);
}
public boolean checkIfSubtypeBelongsToThisImeAndImplicitlyEnabled(
@@ -258,7 +278,7 @@ public final class RichInputMethodManager {
}
public boolean checkIfSubtypeBelongsToThisIme(final InputMethodSubtype subtype) {
- return getSubtypeIndexInIme(subtype, mInputMethodInfoOfThisIme) != INDEX_NOT_FOUND;
+ return getSubtypeIndexInIme(subtype, getInputMethodInfoOfThisIme()) != INDEX_NOT_FOUND;
}
private static int getSubtypeIndexInIme(final InputMethodSubtype subtype,
@@ -286,7 +306,8 @@ public final class RichInputMethodManager {
public boolean hasMultipleEnabledSubtypesInThisIme(
final boolean shouldIncludeAuxiliarySubtypes) {
- final List<InputMethodInfo> imiList = Collections.singletonList(mInputMethodInfoOfThisIme);
+ final List<InputMethodInfo> imiList = Collections.singletonList(
+ getInputMethodInfoOfThisIme());
return hasMultipleEnabledSubtypes(shouldIncludeAuxiliarySubtypes, imiList);
}
@@ -340,7 +361,7 @@ public final class RichInputMethodManager {
public InputMethodSubtype findSubtypeByLocaleAndKeyboardLayoutSet(final String localeString,
final String keyboardLayoutSetName) {
- final InputMethodInfo myImi = mInputMethodInfoOfThisIme;
+ final InputMethodInfo myImi = getInputMethodInfoOfThisIme();
final int count = myImi.getSubtypeCount();
for (int i = 0; i < count; i++) {
final InputMethodSubtype subtype = myImi.getSubtypeAt(i);
@@ -355,13 +376,14 @@ public final class RichInputMethodManager {
public void setInputMethodAndSubtype(final IBinder token, final InputMethodSubtype subtype) {
mImmWrapper.mImm.setInputMethodAndSubtype(
- token, mInputMethodInfoOfThisIme.getId(), subtype);
+ token, getInputMethodIdOfThisIme(), subtype);
}
public void setAdditionalInputMethodSubtypes(final InputMethodSubtype[] subtypes) {
mImmWrapper.mImm.setAdditionalInputMethodSubtypes(
- mInputMethodInfoOfThisIme.getId(), subtypes);
- // Clear the cache so that we go read the subtypes again next time.
+ getInputMethodIdOfThisIme(), subtypes);
+ // Clear the cache so that we go read the {@link InputMethodInfo} of this IME and list of
+ // subtypes again next time.
clearSubtypeCaches();
}
@@ -382,5 +404,6 @@ public final class RichInputMethodManager {
public void clearSubtypeCaches() {
mSubtypeListCacheWithImplicitlySelectedSubtypes.clear();
mSubtypeListCacheWithoutImplicitlySelectedSubtypes.clear();
+ mInputMethodInfoCache.clear();
}
}
diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java
index df25b0c29..ba64028ca 100644
--- a/java/src/com/android/inputmethod/latin/Suggest.java
+++ b/java/src/com/android/inputmethod/latin/Suggest.java
@@ -60,6 +60,7 @@ public final class Suggest {
// Locale used for upper- and title-casing words
public final Locale mLocale;
+ // TODO: Move dictionaryFacilitator constructing logics from LatinIME to Suggest.
public Suggest(final Locale locale,
final DictionaryFacilitatorForSuggest dictionaryFacilitator) {
mLocale = locale;
diff --git a/java/src/com/android/inputmethod/latin/SuggestedWords.java b/java/src/com/android/inputmethod/latin/SuggestedWords.java
index 06bc90c97..dc2c9fd0e 100644
--- a/java/src/com/android/inputmethod/latin/SuggestedWords.java
+++ b/java/src/com/android/inputmethod/latin/SuggestedWords.java
@@ -167,15 +167,10 @@ public class SuggestedWords {
final CompletionInfo[] infos) {
final ArrayList<SuggestedWordInfo> result = CollectionUtils.newArrayList();
for (final CompletionInfo info : infos) {
- if (info == null) continue;
- final CharSequence text = info.getText();
- if (null == text) continue;
- final SuggestedWordInfo suggestedWordInfo = new SuggestedWordInfo(text.toString(),
- SuggestedWordInfo.MAX_SCORE, SuggestedWordInfo.KIND_APP_DEFINED,
- Dictionary.DICTIONARY_APPLICATION_DEFINED,
- SuggestedWordInfo.NOT_AN_INDEX /* indexOfTouchPointOfSecondWord */,
- SuggestedWordInfo.NOT_A_CONFIDENCE /* autoCommitFirstWordConfidence */);
- result.add(suggestedWordInfo);
+ if (null == info || null == info.getText()) {
+ continue;
+ }
+ result.add(new SuggestedWordInfo(info));
}
return result;
}
@@ -234,6 +229,9 @@ public class SuggestedWords {
public static final int KIND_FLAG_EXACT_MATCH = 0x40000000;
public final String mWord;
+ // The completion info from the application. Null for suggestions that don't come from
+ // the application (including keyboard-computed ones, so this is almost always null)
+ public final CompletionInfo mApplicationSpecifiedCompletionInfo;
public final int mScore;
public final int mKind; // one of the KIND_* constants above
public final int mCodePointCount;
@@ -260,6 +258,7 @@ public class SuggestedWords {
final Dictionary sourceDict, final int indexOfTouchPointOfSecondWord,
final int autoCommitFirstWordConfidence) {
mWord = word;
+ mApplicationSpecifiedCompletionInfo = null;
mScore = score;
mKind = kind;
mSourceDict = sourceDict;
@@ -268,6 +267,22 @@ public class SuggestedWords {
mAutoCommitFirstWordConfidence = autoCommitFirstWordConfidence;
}
+ /**
+ * Create a new suggested word info from an application-specified completion.
+ * If the passed argument or its contained text is null, this throws a NPE.
+ * @param applicationSpecifiedCompletion The application-specified completion info.
+ */
+ public SuggestedWordInfo(final CompletionInfo applicationSpecifiedCompletion) {
+ mWord = applicationSpecifiedCompletion.getText().toString();
+ mApplicationSpecifiedCompletionInfo = applicationSpecifiedCompletion;
+ mScore = SuggestedWordInfo.MAX_SCORE;
+ mKind = SuggestedWordInfo.KIND_APP_DEFINED;
+ mSourceDict = Dictionary.DICTIONARY_APPLICATION_DEFINED;
+ mCodePointCount = StringUtils.codePointCount(mWord);
+ mIndexOfTouchPointOfSecondWord = SuggestedWordInfo.NOT_AN_INDEX;
+ mAutoCommitFirstWordConfidence = SuggestedWordInfo.NOT_A_CONFIDENCE;
+ }
+
public boolean isEligibleForAutoCommit() {
return (KIND_CORRECTION == mKind && NOT_AN_INDEX != mIndexOfTouchPointOfSecondWord);
}
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index f2f9f1e68..daaac5913 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -23,12 +23,12 @@ import android.text.style.SuggestionSpan;
import android.util.Log;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
-import android.view.inputmethod.CompletionInfo;
import android.view.inputmethod.CorrectionInfo;
import android.view.inputmethod.EditorInfo;
import com.android.inputmethod.compat.SuggestionSpanUtils;
import com.android.inputmethod.event.EventInterpreter;
+import com.android.inputmethod.event.InputTransaction;
import com.android.inputmethod.keyboard.KeyboardSwitcher;
import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.Dictionary;
@@ -74,7 +74,7 @@ public final class InputLogic {
// TODO : make all these fields private as soon as possible.
// Current space state of the input method. This can be any of the above constants.
- public int mSpaceState;
+ private int mSpaceState;
// Never null
public SuggestedWords mSuggestedWords = SuggestedWords.EMPTY;
// TODO: mSuggest should be touched by a single thread.
@@ -85,7 +85,7 @@ public final class InputLogic {
public LastComposedWord mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD;
public final WordComposer mWordComposer;
public final RichInputConnection mConnection;
- public final RecapitalizeStatus mRecapitalizeStatus = new RecapitalizeStatus();
+ private final RecapitalizeStatus mRecapitalizeStatus = new RecapitalizeStatus();
private int mDeleteCount;
private long mLastKeyTime;
@@ -96,7 +96,7 @@ public final class InputLogic {
// TODO: This boolean is persistent state and causes large side effects at unexpected times.
// Find a way to remove it for readability.
- public boolean mIsAutoCorrectionIndicatorOn;
+ private boolean mIsAutoCorrectionIndicatorOn;
public InputLogic(final LatinIME latinIME,
final SuggestionStripViewAccessor suggestionStripViewAccessor) {
@@ -227,17 +227,16 @@ public final class InputLogic {
}
}
- // TODO: stop relying on mApplicationSpecifiedCompletions. The SuggestionInfo object
- // should contain a reference to the CompletionInfo instead.
- if (settingsValues.isApplicationSpecifiedCompletionsOn()
- && mLatinIME.mApplicationSpecifiedCompletions != null
- && index >= 0 && index < mLatinIME.mApplicationSpecifiedCompletions.length) {
+ // TODO: We should not need the following branch. We should be able to take the same
+ // code path as for other kinds, use commitChosenWord, and do everything normally. We will
+ // however need to reset the suggestion strip right away, because we know we can't take
+ // the risk of calling commitCompletion twice because we don't know how the app will react.
+ if (SuggestedWordInfo.KIND_APP_DEFINED == suggestionInfo.mKind) {
mSuggestedWords = SuggestedWords.EMPTY;
mSuggestionStripViewAccessor.setNeutralSuggestionStrip();
keyboardSwitcher.updateShiftState();
resetComposingState(true /* alsoResetLastComposedWord */);
- final CompletionInfo completionInfo = mLatinIME.mApplicationSpecifiedCompletions[index];
- mConnection.commitCompletion(completionInfo);
+ mConnection.commitCompletion(suggestionInfo.mApplicationSpecifiedCompletionInfo);
mConnection.endBatchEdit();
return;
}
@@ -290,19 +289,14 @@ public final class InputLogic {
* Consider an update to the cursor position. Evaluate whether this update has happened as
* part of normal typing or whether it was an explicit cursor move by the user. In any case,
* do the necessary adjustments.
- * @param settingsValues the current settings
* @param oldSelStart old selection start
* @param oldSelEnd old selection end
* @param newSelStart new selection start
* @param newSelEnd new selection end
- * @param composingSpanStart composing span start
- * @param composingSpanEnd composing span end
* @return whether the cursor has moved as a result of user interaction.
*/
- public boolean onUpdateSelection(final SettingsValues settingsValues,
- final int oldSelStart, final int oldSelEnd,
- final int newSelStart, final int newSelEnd,
- final int composingSpanStart, final int composingSpanEnd) {
+ public boolean onUpdateSelection(final int oldSelStart, final int oldSelEnd,
+ final int newSelStart, final int newSelEnd) {
if (mConnection.isBelatedExpectedUpdate(oldSelStart, newSelStart, oldSelEnd, newSelEnd)) {
return false;
}
@@ -335,8 +329,7 @@ public final class InputLogic {
// we'd have the suggestion strip noticeably janky. To avoid that, we don't clear
// it here, which means we'll keep outdated suggestions for a split second but the
// visual result is better.
- resetEntireInputState(settingsValues, newSelStart, newSelEnd,
- false /* clearSuggestionStrip */);
+ resetEntireInputState(newSelStart, newSelEnd, false /* clearSuggestionStrip */);
} else {
// resetEntireInputState calls resetCachesUponCursorMove, but forcing the
// composition to end. But in all cases where we don't reset the entire input
@@ -372,6 +365,8 @@ public final class InputLogic {
ResearchLogger.latinIME_onCodeInput(code, x, y);
}
final long when = SystemClock.uptimeMillis();
+ final InputTransaction inputTransaction = new InputTransaction(
+ getActualCapsMode(settingsValues, keyboardSwitcher.getKeyboardShiftMode()));
if (code != Constants.CODE_DELETE
|| when > mLastKeyTime + Constants.LONG_PRESS_MILLISECONDS) {
mDeleteCount = 0;
@@ -396,12 +391,12 @@ public final class InputLogic {
boolean didAutoCorrect = false;
switch (code) {
case Constants.CODE_DELETE:
- handleBackspace(settingsValues, spaceState, handler, keyboardSwitcher);
+ handleBackspace(settingsValues, spaceState, inputTransaction, handler);
LatinImeLogger.logOnDelete(x, y);
break;
case Constants.CODE_SHIFT:
performRecapitalization(settingsValues);
- keyboardSwitcher.updateShiftState();
+ inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
break;
case Constants.CODE_CAPSLOCK:
// Note: Changing keyboard to shift lock state is handled in
@@ -456,12 +451,12 @@ public final class InputLogic {
// No action label, and the action from imeOptions is NONE: this is a regular
// enter key that should input a carriage return.
didAutoCorrect = handleNonSpecialCharacter(settingsValues, Constants.CODE_ENTER,
- x, y, spaceState, keyboardSwitcher, handler);
+ x, y, spaceState, inputTransaction, handler);
}
break;
case Constants.CODE_SHIFT_ENTER:
didAutoCorrect = handleNonSpecialCharacter(settingsValues, Constants.CODE_ENTER,
- x, y, spaceState, keyboardSwitcher, handler);
+ x, y, spaceState, inputTransaction, handler);
break;
case Constants.CODE_ALPHA_FROM_EMOJI:
// Note: Switching back from Emoji keyboard to the main keyboard is being handled in
@@ -469,7 +464,7 @@ public final class InputLogic {
break;
default:
didAutoCorrect = handleNonSpecialCharacter(settingsValues,
- code, x, y, spaceState, keyboardSwitcher, handler);
+ code, x, y, spaceState, inputTransaction, handler);
break;
}
// Reset after any single keystroke, except shift, capslock, and symbol-shift
@@ -481,6 +476,15 @@ public final class InputLogic {
mEnteredText = null;
}
mConnection.endBatchEdit();
+ switch (inputTransaction.getRequiredShiftUpdate()) {
+ case InputTransaction.SHIFT_UPDATE_LATER:
+ mLatinIME.mHandler.postUpdateShiftState();
+ break;
+ case InputTransaction.SHIFT_UPDATE_NOW:
+ keyboardSwitcher.updateShiftState();
+ break;
+ default: // SHIFT_NO_UPDATE
+ }
}
public void onStartBatchInput(final SettingsValues settingsValues,
@@ -504,7 +508,7 @@ public final class InputLogic {
if (mWordComposer.isCursorFrontOrMiddleOfComposingWord()) {
// If we are in the middle of a recorrection, we need to commit the recorrection
// first so that we can insert the batch input at the current cursor position.
- resetEntireInputState(settingsValues, mConnection.getExpectedSelectionStart(),
+ resetEntireInputState(mConnection.getExpectedSelectionStart(),
mConnection.getExpectedSelectionEnd(), true /* clearSuggestionStrip */);
} else if (wordComposerSize <= 1) {
// We auto-correct the previous (typed, not gestured) string iff it's one character
@@ -585,8 +589,7 @@ public final class InputLogic {
mInputLogicHandler.onUpdateBatchInput(batchPointers, mAutoCommitSequenceNumber);
}
- public void onEndBatchInput(final SettingsValues settingValues,
- final InputPointers batchPointers) {
+ public void onEndBatchInput(final InputPointers batchPointers) {
mInputLogicHandler.onEndBatchInput(batchPointers, mAutoCommitSequenceNumber);
++mAutoCommitSequenceNumber;
}
@@ -630,18 +633,20 @@ public final class InputLogic {
* @param x the x-coordinate of the key press, or Contants.NOT_A_COORDINATE if not applicable.
* @param y the y-coordinate of the key press, or Contants.NOT_A_COORDINATE if not applicable.
* @param spaceState the space state at start of the batch input.
+ * @param inputTransaction The transaction in progress.
* @return whether this caused an auto-correction to happen.
*/
private boolean handleNonSpecialCharacter(final SettingsValues settingsValues,
final int codePoint, final int x, final int y, final int spaceState,
- // TODO: remove these arguments
- final KeyboardSwitcher keyboardSwitcher, final LatinIME.UIHandler handler) {
+ final InputTransaction inputTransaction,
+ // TODO: remove this argument
+ final LatinIME.UIHandler handler) {
mSpaceState = SpaceState.NONE;
final boolean didAutoCorrect;
if (settingsValues.isWordSeparator(codePoint)
|| Character.getType(codePoint) == Character.OTHER_SYMBOL) {
didAutoCorrect = handleSeparator(settingsValues, codePoint,
- Constants.SUGGESTION_STRIP_COORDINATE == x, spaceState, keyboardSwitcher,
+ Constants.SUGGESTION_STRIP_COORDINATE == x, spaceState, inputTransaction,
handler);
if (settingsValues.mIsInternal) {
LatinImeLoggerUtils.onSeparator((char)codePoint, x, y);
@@ -658,14 +663,14 @@ public final class InputLogic {
if (mWordComposer.isCursorFrontOrMiddleOfComposingWord()) {
// If we are in the middle of a recorrection, we need to commit the recorrection
// first so that we can insert the character at the current cursor position.
- resetEntireInputState(settingsValues, mConnection.getExpectedSelectionStart(),
+ resetEntireInputState(mConnection.getExpectedSelectionStart(),
mConnection.getExpectedSelectionEnd(), true /* clearSuggestionStrip */);
} else {
commitTyped(settingsValues, LastComposedWord.NOT_A_SEPARATOR);
}
}
handleNonSeparator(settingsValues, codePoint, x, y, spaceState,
- keyboardSwitcher, handler);
+ inputTransaction, handler);
}
return didAutoCorrect;
}
@@ -677,11 +682,13 @@ public final class InputLogic {
* @param x the x-coordinate of the key press, or Contants.NOT_A_COORDINATE if not applicable.
* @param y the y-coordinate of the key press, or Contants.NOT_A_COORDINATE if not applicable.
* @param spaceState the space state at start of the batch input.
+ * @param inputTransaction The transaction in progress.
*/
private void handleNonSeparator(final SettingsValues settingsValues,
final int codePoint, final int x, final int y, final int spaceState,
- // TODO: Remove these arguments
- final KeyboardSwitcher keyboardSwitcher, final LatinIME.UIHandler handler) {
+ final InputTransaction inputTransaction,
+ // TODO: Remove this argument
+ final LatinIME.UIHandler handler) {
// TODO: refactor this method to stop flipping isComposingWord around all the time, and
// make it shorter (possibly cut into several pieces). Also factor handleNonSpecialCharacter
// which has the same name as other handle* methods but is not the same.
@@ -700,7 +707,7 @@ public final class InputLogic {
if (mWordComposer.isCursorFrontOrMiddleOfComposingWord()) {
// If we are in the middle of a recorrection, we need to commit the recorrection
// first so that we can insert the character at the current cursor position.
- resetEntireInputState(settingsValues, mConnection.getExpectedSelectionStart(),
+ resetEntireInputState(mConnection.getExpectedSelectionStart(),
mConnection.getExpectedSelectionEnd(), true /* clearSuggestionStrip */);
isComposingWord = false;
}
@@ -737,8 +744,7 @@ public final class InputLogic {
// We pass 1 to getPreviousWordForSuggestion because we were not composing a word
// yet, so the word we want is the 1st word before the cursor.
mWordComposer.setCapitalizedModeAndPreviousWordAtStartComposingTime(
- getActualCapsMode(settingsValues, keyboardSwitcher.getKeyboardShiftMode()),
- getNthPreviousWordForSuggestion(
+ inputTransaction.mShiftState, getNthPreviousWordForSuggestion(
settingsValues.mSpacingAndPunctuations, 1 /* nthPreviousWord */));
}
mConnection.setComposingText(getTextWithUnderline(
@@ -750,7 +756,7 @@ public final class InputLogic {
sendKeyCodePoint(settingsValues, codePoint);
if (swapWeakSpace) {
- swapSwapperAndSpace(keyboardSwitcher);
+ swapSwapperAndSpace(inputTransaction);
mSpaceState = SpaceState.WEAK;
}
// In case the "add to dictionary" hint was still displayed.
@@ -768,12 +774,14 @@ public final class InputLogic {
* @param codePoint the code point associated with the key.
* @param isFromSuggestionStrip whether this code point comes from the suggestion strip.
* @param spaceState the space state at start of the batch input.
+ * @param inputTransaction The transaction in progress.
* @return whether this caused an auto-correction to happen.
*/
private boolean handleSeparator(final SettingsValues settingsValues,
final int codePoint, final boolean isFromSuggestionStrip, final int spaceState,
- // TODO: remove these arguments
- final KeyboardSwitcher keyboardSwitcher, final LatinIME.UIHandler handler) {
+ final InputTransaction inputTransaction,
+ // TODO: remove this argument
+ final LatinIME.UIHandler handler) {
boolean didAutoCorrect = false;
// We avoid sending spaces in languages without spaces if we were composing.
final boolean shouldAvoidSendingCode = Constants.CODE_SPACE == codePoint
@@ -782,7 +790,7 @@ public final class InputLogic {
if (mWordComposer.isCursorFrontOrMiddleOfComposingWord()) {
// If we are in the middle of a recorrection, we need to commit the recorrection
// first so that we can insert the separator at the current cursor position.
- resetEntireInputState(settingsValues, mConnection.getExpectedSelectionStart(),
+ resetEntireInputState(mConnection.getExpectedSelectionStart(),
mConnection.getExpectedSelectionEnd(), true /* clearSuggestionStrip */);
}
// isComposingWord() may have changed since we stored wasComposing
@@ -828,7 +836,7 @@ public final class InputLogic {
if (Constants.CODE_SPACE == codePoint) {
if (settingsValues.isSuggestionsRequested()) {
if (maybeDoubleSpacePeriod(settingsValues, handler)) {
- keyboardSwitcher.updateShiftState();
+ inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
mSpaceState = SpaceState.DOUBLE;
} else if (!mSuggestedWords.isPunctuationSuggestions()) {
mSpaceState = SpaceState.WEAK;
@@ -839,7 +847,7 @@ public final class InputLogic {
handler.postUpdateSuggestionStrip();
} else {
if (swapWeakSpace) {
- swapSwapperAndSpace(keyboardSwitcher);
+ swapSwapperAndSpace(inputTransaction);
mSpaceState = SpaceState.SWAP_PUNCTUATION;
} else if ((SpaceState.PHANTOM == spaceState
&& settingsValues.isUsuallyFollowedBySpace(codePoint))
@@ -864,7 +872,7 @@ public final class InputLogic {
mSuggestionStripViewAccessor.setNeutralSuggestionStrip();
}
- keyboardSwitcher.updateShiftState();
+ inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
return didAutoCorrect;
}
@@ -872,23 +880,24 @@ public final class InputLogic {
* Handle a press on the backspace key.
* @param settingsValues The current settings values.
* @param spaceState The space state at start of this batch edit.
+ * @param inputTransaction The transaction in progress.
*/
private void handleBackspace(final SettingsValues settingsValues, final int spaceState,
- // TODO: remove these arguments
- final LatinIME.UIHandler handler, final KeyboardSwitcher keyboardSwitcher) {
+ final InputTransaction inputTransaction,
+ // TODO: remove this argument
+ final LatinIME.UIHandler handler) {
mSpaceState = SpaceState.NONE;
- final int deleteCountAtStart = mDeleteCount;
mDeleteCount++;
// 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
// during key repeat.
- handler.postUpdateShiftState();
+ inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_LATER);
if (mWordComposer.isCursorFrontOrMiddleOfComposingWord()) {
// If we are in the middle of a recorrection, we need to commit the recorrection
// first so that we can remove the character at the current cursor position.
- resetEntireInputState(settingsValues, mConnection.getExpectedSelectionStart(),
+ resetEntireInputState(mConnection.getExpectedSelectionStart(),
mConnection.getExpectedSelectionEnd(), true /* clearSuggestionStrip */);
// When we exit this if-clause, mWordComposer.isComposingWord() will return false.
}
@@ -909,7 +918,7 @@ public final class InputLogic {
if (!mWordComposer.isComposingWord()) {
// If we just removed the last character, auto-caps mode may have changed so we
// need to re-evaluate.
- keyboardSwitcher.updateShiftState();
+ inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
}
} else {
if (mLastComposedWord.canRevertCommit()) {
@@ -1021,7 +1030,7 @@ public final class InputLogic {
true /* includeResumedWordInSuggestions */);
}
// We just removed at least one character. We need to update the auto-caps state.
- keyboardSwitcher.updateShiftState();
+ inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
}
}
@@ -1037,9 +1046,9 @@ public final class InputLogic {
*
* This method will check that there are two characters before the cursor and that the first
* one is a space before it does the actual swapping.
+ * @param inputTransaction The transaction in progress.
*/
- // TODO: Remove this argument
- private void swapSwapperAndSpace(final KeyboardSwitcher keyboardSwitcher) {
+ private void swapSwapperAndSpace(final InputTransaction inputTransaction) {
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) == Constants.CODE_SPACE) {
@@ -1049,7 +1058,7 @@ public final class InputLogic {
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
ResearchLogger.latinIME_swapSwapperAndSpace(lastTwo, text);
}
- keyboardSwitcher.updateShiftState();
+ inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
}
}
@@ -1205,11 +1214,7 @@ public final class InputLogic {
timeStampInSeconds);
}
- public void performUpdateSuggestionStripSync(final SettingsValues settingsValues,
- // TODO: Remove this argument
- final LatinIME.UIHandler handler) {
- handler.cancelUpdateSuggestionStrip();
-
+ public void performUpdateSuggestionStripSync(final SettingsValues settingsValues) {
// Check if we have a suggestion engine attached.
if (mSuggest == null || !settingsValues.isSuggestionsRequested()) {
if (mWordComposer.isComposingWord()) {
@@ -1229,11 +1234,15 @@ public final class InputLogic {
SuggestedWords.NOT_A_SEQUENCE_NUMBER, new OnGetSuggestedWordsCallback() {
@Override
public void onGetSuggestedWords(final SuggestedWords suggestedWords) {
- final SuggestedWords suggestedWordsWithMaybeOlderSuggestions =
- mLatinIME.maybeRetrieveOlderSuggestions(
- mWordComposer.getTypedWord(), suggestedWords,
- mSuggestedWords);
- holder.set(suggestedWordsWithMaybeOlderSuggestions);
+ final String typedWord = mWordComposer.getTypedWord();
+ // Show new suggestions if we have at least one. Otherwise keep the old
+ // suggestions with the new typed word. Exception: if the length of the
+ // typed word is <= 1 (after a deletion typically) we clear old suggestions.
+ if (suggestedWords.size() > 1 || typedWord.length() <= 1) {
+ holder.set(suggestedWords);
+ } else {
+ holder.set(retrieveOlderSuggestions(typedWord, mSuggestedWords));
+ }
}
}
);
@@ -1485,7 +1494,9 @@ public final class InputLogic {
*/
private int getActualCapsMode(final SettingsValues settingsValues,
final int keyboardShiftMode) {
- if (keyboardShiftMode != WordComposer.CAPS_MODE_AUTO_SHIFTED) return keyboardShiftMode;
+ if (keyboardShiftMode != WordComposer.CAPS_MODE_AUTO_SHIFTED) {
+ return keyboardShiftMode;
+ }
final int auto = getCurrentAutoCapsState(settingsValues);
if (0 != (auto & TextUtils.CAP_MODE_CHARACTERS)) {
return WordComposer.CAPS_MODE_AUTO_SHIFT_LOCKED;
@@ -1623,15 +1634,13 @@ public final class InputLogic {
* This will clear the composing word, reset the last composed word, clear the suggestion
* strip and tell the input connection about it so that it can refresh its caches.
*
- * @param settingsValues the current values of the settings.
* @param newSelStart the new selection start, in java characters.
* @param newSelEnd the new selection end, in java characters.
* @param clearSuggestionStrip whether this method should clear the suggestion strip.
*/
// TODO: how is this different from startInput ?!
- // TODO: remove all references to this in LatinIME and make this private
- public void resetEntireInputState(final SettingsValues settingsValues,
- final int newSelStart, final int newSelEnd, final boolean clearSuggestionStrip) {
+ private void resetEntireInputState(final int newSelStart, final int newSelEnd,
+ final boolean clearSuggestionStrip) {
final boolean shouldFinishComposition = mWordComposer.isComposingWord();
resetComposingState(true /* alsoResetLastComposedWord */);
if (clearSuggestionStrip) {
@@ -1649,8 +1658,7 @@ public final class InputLogic {
*
* @param alsoResetLastComposedWord whether to also reset the last composed word.
*/
- // TODO: remove all references to this in LatinIME and make this private.
- public void resetComposingState(final boolean alsoResetLastComposedWord) {
+ private void resetComposingState(final boolean alsoResetLastComposedWord) {
mWordComposer.reset();
if (alsoResetLastComposedWord) {
mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD;
@@ -1658,6 +1666,27 @@ public final class InputLogic {
}
/**
+ * Make a {@link com.android.inputmethod.latin.SuggestedWords} object containing a typed word
+ * and obsolete suggestions.
+ * See {@link com.android.inputmethod.latin.SuggestedWords#getTypedWordAndPreviousSuggestions(
+ * String, com.android.inputmethod.latin.SuggestedWords)}.
+ * @param typedWord The typed word as a string.
+ * @param previousSuggestedWords The previously suggested words.
+ * @return Obsolete suggestions with the newly typed word.
+ */
+ private SuggestedWords retrieveOlderSuggestions(final String typedWord,
+ final SuggestedWords previousSuggestedWords) {
+ final SuggestedWords oldSuggestedWords =
+ previousSuggestedWords.isPunctuationSuggestions() ? SuggestedWords.EMPTY
+ : previousSuggestedWords;
+ final ArrayList<SuggestedWords.SuggestedWordInfo> typedWordAndPreviousSuggestions =
+ SuggestedWords.getTypedWordAndPreviousSuggestions(typedWord, oldSuggestedWords);
+ return new SuggestedWords(typedWordAndPreviousSuggestions, null /* rawSuggestions */,
+ false /* typedWordValid */, false /* hasAutoCorrectionCandidate */,
+ true /* isObsoleteSuggestions */, false /* isPrediction */);
+ }
+
+ /**
* Gets a chunk of text with or the auto-correction indicator underline span as appropriate.
*
* This method looks at the old state of the auto-correction indicator to put or not put
@@ -1674,9 +1703,8 @@ public final class InputLogic {
* @param text the text on which to maybe apply the span.
* @return the same text, with the auto-correction underline span if that's appropriate.
*/
- // TODO: remove all references to this in LatinIME and make this private. Also, shouldn't
- // this go in some *Utils class instead?
- public CharSequence getTextWithUnderline(final String text) {
+ // TODO: Shouldn't this go in some *Utils class instead?
+ private CharSequence getTextWithUnderline(final String text) {
return mIsAutoCorrectionIndicatorOn
? SuggestionSpanUtils.getTextWithAutoCorrectionIndicatorUnderline(mLatinIME, text)
: text;
@@ -1741,8 +1769,7 @@ public final class InputLogic {
*
* @param settingsValues the current values of the settings.
*/
- // TODO: Make this private.
- public void promotePhantomSpace(final SettingsValues settingsValues) {
+ private void promotePhantomSpace(final SettingsValues settingsValues) {
if (settingsValues.shouldInsertSpacesAutomatically()
&& settingsValues.mSpacingAndPunctuations.mCurrentLanguageHasSpaces
&& !mConnection.textBeforeCursorLooksLikeURL()) {
@@ -1848,7 +1875,8 @@ public final class InputLogic {
final LatinIME.UIHandler handler) {
// Complete any pending suggestions query first
if (handler.hasPendingUpdateSuggestions()) {
- performUpdateSuggestionStripSync(settingsValues, handler);
+ handler.cancelUpdateSuggestionStrip();
+ performUpdateSuggestionStripSync(settingsValues);
}
final String typedAutoCorrection = mWordComposer.getAutoCorrectionOrNull();
final String typedWord = mWordComposer.getTypedWord();
@@ -1892,8 +1920,7 @@ public final class InputLogic {
* @param commitType the type of the commit, as one of LastComposedWord.COMMIT_TYPE_*
* @param separatorString the separator that's causing the commit, or NOT_A_SEPARATOR if none.
*/
- // TODO: Make this private
- public void commitChosenWord(final SettingsValues settingsValues, final String chosenWord,
+ private void commitChosenWord(final SettingsValues settingsValues, final String chosenWord,
final int commitType, final String separatorString) {
final SuggestedWords suggestedWords = mSuggestedWords;
final CharSequence chosenWordWithSuggestions =
diff --git a/java/src/com/android/inputmethod/latin/settings/DebugSettings.java b/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
index c87dd1589..11d369282 100644
--- a/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
+++ b/java/src/com/android/inputmethod/latin/settings/DebugSettings.java
@@ -42,8 +42,6 @@ public final class DebugSettings extends PreferenceFragment
public static final String PREF_FORCE_NON_DISTINCT_MULTITOUCH = "force_non_distinct_multitouch";
public static final String PREF_USABILITY_STUDY_MODE = "usability_study_mode";
public static final String PREF_STATISTICS_LOGGING = "enable_logging";
- public static final String PREF_USE_ONLY_PERSONALIZATION_DICTIONARY_FOR_DEBUG =
- "use_only_personalization_dictionary_for_debug";
public static final String PREF_KEY_PREVIEW_SHOW_UP_START_SCALE =
"pref_key_preview_show_up_start_scale";
public static final String PREF_KEY_PREVIEW_DISMISS_END_SCALE =
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
index 77968f79a..50fbbb19f 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsValues.java
@@ -84,7 +84,6 @@ public final class SettingsValues {
public final float mAutoCorrectionThreshold;
public final boolean mCorrectionEnabled;
public final int mSuggestionVisibility;
- public final boolean mUseOnlyPersonalizationDictionaryForDebug;
public final int mDisplayOrientation;
private final AsyncResultHolder<AppWorkaroundsUtils> mAppWorkarounds;
@@ -168,8 +167,6 @@ public final class SettingsValues {
prefs, DebugSettings.PREF_KEY_PREVIEW_DISMISS_END_SCALE,
ResourceUtils.getFloatFromFraction(
res, R.fraction.config_key_preview_dismiss_end_scale));
- mUseOnlyPersonalizationDictionaryForDebug = prefs.getBoolean(
- DebugSettings.PREF_USE_ONLY_PERSONALIZATION_DICTIONARY_FOR_DEBUG, false);
mDisplayOrientation = res.getConfiguration().orientation;
mAppWorkarounds = new AsyncResultHolder<AppWorkaroundsUtils>();
final PackageInfo packageInfo = TargetPackageInfoGetterTask.getCachedPackageInfo(
@@ -390,8 +387,6 @@ public final class SettingsValues {
sb.append("" + mCorrectionEnabled);
sb.append("\n mSuggestionVisibility = ");
sb.append("" + mSuggestionVisibility);
- sb.append("\n mUseOnlyPersonalizationDictionaryForDebug = ");
- sb.append("" + mUseOnlyPersonalizationDictionaryForDebug);
sb.append("\n mDisplayOrientation = ");
sb.append("" + mDisplayOrientation);
sb.append("\n mAppWorkarounds = ");
diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
index 4ef562d8f..43cb11b14 100644
--- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
+++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java
@@ -35,7 +35,6 @@ import android.widget.RelativeLayout;
import android.widget.TextView;
import com.android.inputmethod.keyboard.Keyboard;
-import com.android.inputmethod.keyboard.KeyboardSwitcher;
import com.android.inputmethod.keyboard.MainKeyboardView;
import com.android.inputmethod.keyboard.MoreKeysPanel;
import com.android.inputmethod.latin.AudioAndHapticFeedbackManager;
@@ -281,8 +280,8 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
private final MoreKeysPanel.Controller mMoreSuggestionsController =
new MoreKeysPanel.Controller() {
@Override
- public void onDismissMoreKeysPanel(final MoreKeysPanel panel) {
- mMainKeyboardView.onDismissMoreKeysPanel(panel);
+ public void onDismissMoreKeysPanel() {
+ mMainKeyboardView.onDismissMoreKeysPanel();
}
@Override
@@ -291,7 +290,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
}
@Override
- public void onCancelMoreKeysPanel(final MoreKeysPanel panel) {
+ public void onCancelMoreKeysPanel() {
dismissMoreSuggestionsPanel();
}
};
@@ -312,7 +311,7 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
}
boolean showMoreSuggestions() {
- final Keyboard parentKeyboard = KeyboardSwitcher.getInstance().getKeyboard();
+ final Keyboard parentKeyboard = mMainKeyboardView.getKeyboard();
if (parentKeyboard == null) {
return false;
}
@@ -320,6 +319,12 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
if (!layoutHelper.mMoreSuggestionsAvailable) {
return false;
}
+ // Dismiss another {@link MoreKeysPanel} that may be being showed, for example
+ // {@link MoreKeysKeyboardView}.
+ mMainKeyboardView.onDismissMoreKeysPanel();
+ // Dismiss all key previews and sliding key input preview that may be being showed.
+ mMainKeyboardView.dismissAllKeyPreviews();
+ mMainKeyboardView.dismissSlidingKeyInputPreview();
final int stripWidth = getWidth();
final View container = mMoreSuggestionsContainer;
final int maxWidth = stripWidth - container.getPaddingLeft() - container.getPaddingRight();
diff --git a/java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java b/java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java
index ef1d0f42c..2bb30a2ba 100644
--- a/java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/AdditionalSubtypeUtils.java
@@ -27,6 +27,7 @@ import android.text.TextUtils;
import android.util.Log;
import android.view.inputmethod.InputMethodSubtype;
+import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.compat.InputMethodSubtypeCompatUtils;
import com.android.inputmethod.latin.R;
@@ -42,6 +43,7 @@ public final class AdditionalSubtypeUtils {
// This utility class is not publicly instantiable.
}
+ @UsedForTesting
public static boolean isAdditionalSubtype(final InputMethodSubtype subtype) {
return subtype.containsExtraValueKey(IS_ADDITIONAL_SUBTYPE);
}