aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--java/src/com/android/inputmethod/event/InputTransaction.java25
-rw-r--r--java/src/com/android/inputmethod/keyboard/MainKeyboardView.java7
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java18
-rw-r--r--java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java47
-rw-r--r--java/src/com/android/inputmethod/latin/inputlogic/InputLogicHandler.java6
-rw-r--r--java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java11
-rw-r--r--java/src/com/android/inputmethod/latin/utils/SpacebarLanguageUtils.java61
-rw-r--r--java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java35
-rw-r--r--native/jni/src/suggest/core/result/suggestions_output_utils.cpp161
-rw-r--r--native/jni/src/suggest/core/result/suggestions_output_utils.h8
-rw-r--r--native/jni/src/suggest/core/session/dic_traverse_session.cpp1
-rw-r--r--native/jni/src/suggest/core/session/dic_traverse_session.h5
-rw-r--r--tests/src/com/android/inputmethod/latin/utils/SpacebarLanguagetUtilsTests.java251
-rw-r--r--tests/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtilsTests.java171
14 files changed, 504 insertions, 303 deletions
diff --git a/java/src/com/android/inputmethod/event/InputTransaction.java b/java/src/com/android/inputmethod/event/InputTransaction.java
index 2e9014f20..4fe9b403e 100644
--- a/java/src/com/android/inputmethod/event/InputTransaction.java
+++ b/java/src/com/android/inputmethod/event/InputTransaction.java
@@ -40,6 +40,7 @@ public class InputTransaction {
// Outputs
private int mRequiredShiftUpdate = SHIFT_NO_UPDATE;
+ private boolean mRequiresUpdateSuggestions = false;
public InputTransaction(final SettingsValues settingsValues, final Event event,
final long timestamp, final int spaceState, final int shiftState) {
@@ -50,10 +51,34 @@ public class InputTransaction {
mShiftState = shiftState;
}
+ /**
+ * Indicate that this transaction requires some type of shift update.
+ * @param updateType What type of shift update this requires.
+ */
public void requireShiftUpdate(final int updateType) {
mRequiredShiftUpdate = Math.max(mRequiredShiftUpdate, updateType);
}
+
+ /**
+ * Gets what type of shift update this transaction requires.
+ * @return The shift update type.
+ */
public int getRequiredShiftUpdate() {
return mRequiredShiftUpdate;
}
+
+ /**
+ * Indicate that this transaction requires updating the suggestions.
+ */
+ public void setRequiresUpdateSuggestions() {
+ mRequiresUpdateSuggestions = true;
+ }
+
+ /**
+ * Find out whether this transaction requires updating the suggestions.
+ * @return Whether this transaction requires updating the suggestions.
+ */
+ public boolean requiresUpdateSuggestions() {
+ return mRequiresUpdateSuggestions;
+ }
}
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index 8246c924b..03425ef1f 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -60,7 +60,7 @@ import com.android.inputmethod.latin.define.ProductionFlag;
import com.android.inputmethod.latin.settings.DebugSettings;
import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.CoordinateUtils;
-import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
+import com.android.inputmethod.latin.utils.SpacebarLanguageUtils;
import com.android.inputmethod.latin.utils.TypefaceUtils;
import com.android.inputmethod.latin.utils.UsabilityStudyLogUtils;
import com.android.inputmethod.research.ResearchLogger;
@@ -918,14 +918,13 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
// Layout language name on spacebar.
private String layoutLanguageOnSpacebar(final Paint paint,
final InputMethodSubtype subtype, final int width) {
-
// Choose appropriate language name to fit into the width.
- final String fullText = SubtypeLocaleUtils.getFullDisplayName(subtype);
+ final String fullText = SpacebarLanguageUtils.getFullDisplayName(subtype);
if (fitsTextIntoWidth(width, fullText, paint)) {
return fullText;
}
- final String middleText = SubtypeLocaleUtils.getMiddleDisplayName(subtype);
+ final String middleText = SpacebarLanguageUtils.getMiddleDisplayName(subtype);
if (fitsTextIntoWidth(width, middleText, paint)) {
return middleText;
}
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 0c0be82df..53e6232b6 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -38,7 +38,6 @@ import android.net.ConnectivityManager;
import android.os.Debug;
import android.os.IBinder;
import android.os.Message;
-import android.os.SystemClock;
import android.preference.PreferenceManager;
import android.text.InputType;
import android.text.TextUtils;
@@ -1230,7 +1229,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final InputTransaction completeInputTransaction =
mInputLogic.onCodeInput(mSettings.getCurrent(), event,
mKeyboardSwitcher.getKeyboardShiftMode(), mHandler);
- updateShiftModeAfterInputTransaction(completeInputTransaction.getRequiredShiftUpdate());
+ updateStateAfterInputTransaction(completeInputTransaction);
mKeyboardSwitcher.onCodeInput(codePoint);
}
@@ -1450,7 +1449,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
final InputTransaction completeInputTransaction = mInputLogic.onPickSuggestionManually(
mSettings.getCurrent(), index, suggestionInfo,
mKeyboardSwitcher.getKeyboardShiftMode(), mHandler);
- updateShiftModeAfterInputTransaction(completeInputTransaction.getRequiredShiftUpdate());
+ updateStateAfterInputTransaction(completeInputTransaction);
}
@Override
@@ -1488,8 +1487,14 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
}
- private void updateShiftModeAfterInputTransaction(final int requiredShiftUpdate) {
- switch (requiredShiftUpdate) {
+ /**
+ * After an input transaction has been executed, some state must be updated. This includes
+ * the shift state of the keyboard and suggestions. This method looks at the finished
+ * inputTransaction to find out what is necessary and updates the state accordingly.
+ * @param inputTransaction The transaction that has been executed.
+ */
+ private void updateStateAfterInputTransaction(final InputTransaction inputTransaction) {
+ switch (inputTransaction.getRequiredShiftUpdate()) {
case InputTransaction.SHIFT_UPDATE_LATER:
mHandler.postUpdateShiftState();
break;
@@ -1498,6 +1503,9 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
break;
default: // SHIFT_NO_UPDATE
}
+ if (inputTransaction.requiresUpdateSuggestions()) {
+ mHandler.postUpdateSuggestionStrip();
+ }
}
private void hapticAndAudioFeedback(final int code, final int repeatCount) {
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index e2cdbb39c..ec6bd289a 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -130,8 +130,11 @@ public final class InputLogic {
// so we try using some heuristics to find out about these and fix them.
mConnection.tryFixLyingCursorPosition();
cancelDoubleSpacePeriodCountdown();
- mInputLogicHandler.destroy();
- mInputLogicHandler = new InputLogicHandler(mLatinIME, this);
+ if (InputLogicHandler.NULL_HANDLER == mInputLogicHandler) {
+ mInputLogicHandler = new InputLogicHandler(mLatinIME, this);
+ } else {
+ mInputLogicHandler.reset();
+ }
}
/**
@@ -142,8 +145,7 @@ public final class InputLogic {
mConnection.finishComposingText();
}
resetComposingState(true /* alsoResetLastComposedWord */);
- mInputLogicHandler.destroy();
- mInputLogicHandler = InputLogicHandler.NULL_HANDLER;
+ mInputLogicHandler.reset();
}
/**
@@ -403,7 +405,7 @@ public final class InputLogic {
// A special key, like delete, shift, emoji, or the settings key.
switch (event.mKeyCode) {
case Constants.CODE_DELETE:
- handleBackspace(inputTransaction, handler);
+ handleBackspace(inputTransaction);
LatinImeLogger.logOnDelete(event.mX, event.mY);
break;
case Constants.CODE_SHIFT:
@@ -672,7 +674,7 @@ public final class InputLogic {
commitTyped(inputTransaction.mSettingsValues, LastComposedWord.NOT_A_SEPARATOR);
}
}
- handleNonSeparator(inputTransaction.mSettingsValues, inputTransaction, handler);
+ handleNonSeparator(inputTransaction.mSettingsValues, inputTransaction);
}
return didAutoCorrect;
}
@@ -683,9 +685,7 @@ public final class InputLogic {
* @param inputTransaction The transaction in progress.
*/
private void handleNonSeparator(final SettingsValues settingsValues,
- final InputTransaction inputTransaction,
- // TODO: Remove this argument
- final LatinIME.UIHandler handler) {
+ final InputTransaction inputTransaction) {
final int codePoint = inputTransaction.mEvent.mCodePoint;
// TODO: refactor this method to stop flipping isComposingWord around all the time, and
// make it shorter (possibly cut into several pieces). Also factor handleNonSpecialCharacter
@@ -761,7 +761,7 @@ public final class InputLogic {
// In case the "add to dictionary" hint was still displayed.
mSuggestionStripViewAccessor.dismissAddToDictionaryHint();
}
- handler.postUpdateSuggestionStrip();
+ inputTransaction.setRequiresUpdateSuggestions();
if (settingsValues.mIsInternal) {
LatinImeLoggerUtils.onNonSeparator((char)codePoint, inputTransaction.mEvent.mX,
inputTransaction.mEvent.mY);
@@ -843,7 +843,7 @@ public final class InputLogic {
}
startDoubleSpacePeriodCountdown(inputTransaction);
- handler.postUpdateSuggestionStrip();
+ inputTransaction.setRequiresUpdateSuggestions();
} else {
if (swapWeakSpace) {
swapSwapperAndSpace(inputTransaction);
@@ -879,9 +879,7 @@ public final class InputLogic {
* Handle a press on the backspace key.
* @param inputTransaction The transaction in progress.
*/
- private void handleBackspace(final InputTransaction inputTransaction,
- // TODO: remove this argument
- final LatinIME.UIHandler handler) {
+ private void handleBackspace(final InputTransaction inputTransaction) {
mSpaceState = SpaceState.NONE;
mDeleteCount++;
@@ -910,7 +908,7 @@ public final class InputLogic {
mWordComposer.deleteLast(inputTransaction.mEvent);
}
mConnection.setComposingText(getTextWithUnderline(mWordComposer.getTypedWord()), 1);
- handler.postUpdateSuggestionStrip();
+ inputTransaction.setRequiresUpdateSuggestions();
if (!mWordComposer.isComposingWord()) {
// If we just removed the last character, auto-caps mode may have changed so we
// need to re-evaluate.
@@ -921,7 +919,7 @@ public final class InputLogic {
if (inputTransaction.mSettingsValues.mIsInternal) {
LatinImeLoggerUtils.onAutoCorrectionCancellation();
}
- revertCommit(inputTransaction.mSettingsValues, handler);
+ revertCommit(inputTransaction);
return;
}
if (mEnteredText != null && mConnection.sameAsTextBeforeCursor(mEnteredText)) {
@@ -1400,11 +1398,9 @@ public final class InputLogic {
*
* This is triggered upon pressing backspace just after a commit with auto-correction.
*
- * @param settingsValues the current settings values.
+ * @param inputTransaction The transaction in progress.
*/
- private void revertCommit(final SettingsValues settingsValues,
- // TODO: remove this argument
- final LatinIME.UIHandler handler) {
+ private void revertCommit(final InputTransaction inputTransaction) {
final String previousWord = mLastComposedWord.mPrevWord;
final CharSequence originallyTypedWord = mLastComposedWord.mTypedWord;
final CharSequence committedWord = mLastComposedWord.mCommittedWord;
@@ -1448,7 +1444,8 @@ public final class InputLogic {
// Given this, we add it to the list of suggestions, otherwise we discard it.
if (span instanceof SuggestionSpan) {
final SuggestionSpan suggestionSpan = (SuggestionSpan)span;
- if (!suggestionSpan.getLocale().equals(settingsValues.mLocale.toString())) {
+ if (!suggestionSpan.getLocale().equals(
+ inputTransaction.mSettingsValues.mLocale.toString())) {
continue;
}
for (final String suggestion : suggestionSpan.getSuggestions()) {
@@ -1463,11 +1460,11 @@ public final class InputLogic {
}
}
// Add the suggestion list to the list of suggestions.
- textToCommit.setSpan(new SuggestionSpan(settingsValues.mLocale,
+ textToCommit.setSpan(new SuggestionSpan(inputTransaction.mSettingsValues.mLocale,
suggestions.toArray(new String[suggestions.size()]), 0 /* flags */),
0 /* start */, lastCharIndex /* end */, 0 /* flags */);
}
- if (settingsValues.mSpacingAndPunctuations.mCurrentLanguageHasSpaces) {
+ if (inputTransaction.mSettingsValues.mSpacingAndPunctuations.mCurrentLanguageHasSpaces) {
// For languages with spaces, we revert to the typed string, but the cursor is still
// after the separator so we don't resume suggestions. If the user wants to correct
// the word, they have to press backspace again.
@@ -1480,7 +1477,7 @@ public final class InputLogic {
mLatinIME.getCoordinatesForCurrentKeyboard(codePoints), previousWord);
mConnection.setComposingText(textToCommit, 1);
}
- if (settingsValues.mIsInternal) {
+ if (inputTransaction.mSettingsValues.mIsInternal) {
LatinImeLoggerUtils.onSeparator(mLastComposedWord.mSeparatorString,
Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE);
}
@@ -1493,7 +1490,7 @@ public final class InputLogic {
// separator.
mLastComposedWord = LastComposedWord.NOT_A_COMPOSED_WORD;
// We have a separator between the word and the cursor: we should show predictions.
- handler.postUpdateSuggestionStrip();
+ inputTransaction.setRequiresUpdateSuggestions();
}
/**
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogicHandler.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogicHandler.java
index db96de305..42f0d7c00 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogicHandler.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogicHandler.java
@@ -43,7 +43,7 @@ class InputLogicHandler implements Handler.Callback {
// is initialized, though probably only the monkey can actually do this.
public static final InputLogicHandler NULL_HANDLER = new InputLogicHandler() {
@Override
- public void destroy() {}
+ public void reset() {}
@Override
public boolean handleMessage(final Message msg) { return true; }
@Override
@@ -75,8 +75,8 @@ class InputLogicHandler implements Handler.Callback {
mInputLogic = inputLogic;
}
- public void destroy() {
- mNonUIThreadHandler.getLooper().quit();
+ public void reset() {
+ mNonUIThreadHandler.removeCallbacksAndMessages(null);
}
/**
diff --git a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
index a07e8eb6a..6a52481b9 100644
--- a/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
+++ b/java/src/com/android/inputmethod/latin/spellcheck/AndroidSpellCheckerService.java
@@ -268,6 +268,7 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
// if it doesn't. See documentation for binarySearch.
final int insertIndex = positionIndex >= 0 ? positionIndex : -positionIndex - 1;
+ // Weak <- insertIndex == 0, ..., insertIndex == mLength -> Strong
if (insertIndex == 0 && mLength >= mMaxLength) {
// In the future, we may want to keep track of the best suggestion score even if
// we are asked for 0 suggestions. In this case, we can use the following
@@ -285,11 +286,6 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
// }
return true;
}
- if (insertIndex >= mMaxLength) {
- // We found a suggestion, but its score is too weak to be kept considering
- // the suggestion limit.
- return true;
- }
final String wordString = new String(word, wordOffset, wordLength);
if (mLength < mMaxLength) {
@@ -297,12 +293,13 @@ public final class AndroidSpellCheckerService extends SpellCheckerService
++mLength;
System.arraycopy(mScores, insertIndex, mScores, insertIndex + 1, copyLen);
mSuggestions.add(insertIndex, wordString);
+ mScores[insertIndex] = score;
} else {
- System.arraycopy(mScores, 1, mScores, 0, insertIndex);
+ System.arraycopy(mScores, 1, mScores, 0, insertIndex - 1);
mSuggestions.add(insertIndex, wordString);
mSuggestions.remove(0);
+ mScores[insertIndex - 1] = score;
}
- mScores[insertIndex] = score;
return true;
}
diff --git a/java/src/com/android/inputmethod/latin/utils/SpacebarLanguageUtils.java b/java/src/com/android/inputmethod/latin/utils/SpacebarLanguageUtils.java
new file mode 100644
index 000000000..89837c641
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/utils/SpacebarLanguageUtils.java
@@ -0,0 +1,61 @@
+/*
+ * 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.latin.utils;
+
+import android.view.inputmethod.InputMethodSubtype;
+
+import java.util.Locale;
+
+public final class SpacebarLanguageUtils {
+ private SpacebarLanguageUtils() {
+ // Intentional empty constructor for utility class.
+ }
+
+ // InputMethodSubtype's display name for spacebar text in its locale.
+ // isAdditionalSubtype (T=true, F=false)
+ // locale layout | Middle Full
+ // ------ ------- - --------- ----------------------
+ // en_US qwerty F English English (US) exception
+ // en_GB qwerty F English English (UK) exception
+ // es_US spanish F Español Español (EE.UU.) exception
+ // fr azerty F Français Français
+ // fr_CA qwerty F Français Français (Canada)
+ // fr_CH swiss F Français Français (Suisse)
+ // de qwertz F Deutsch Deutsch
+ // de_CH swiss T Deutsch Deutsch (Schweiz)
+ // zz qwerty F QWERTY QWERTY
+ // fr qwertz T Français Français
+ // de qwerty T Deutsch Deutsch
+ // en_US azerty T English English (US)
+ // zz azerty T AZERTY AZERTY
+ // Get InputMethodSubtype's full display name in its locale.
+ public static String getFullDisplayName(final InputMethodSubtype subtype) {
+ if (SubtypeLocaleUtils.isNoLanguage(subtype)) {
+ return SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(subtype);
+ }
+ return SubtypeLocaleUtils.getSubtypeLocaleDisplayName(subtype.getLocale());
+ }
+
+ // Get InputMethodSubtype's middle display name in its locale.
+ public static String getMiddleDisplayName(final InputMethodSubtype subtype) {
+ if (SubtypeLocaleUtils.isNoLanguage(subtype)) {
+ return SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(subtype);
+ }
+ final Locale locale = SubtypeLocaleUtils.getSubtypeLocale(subtype);
+ return SubtypeLocaleUtils.getSubtypeLocaleDisplayName(locale.getLanguage());
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java b/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java
index 4f556f972..2452864d5 100644
--- a/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java
@@ -292,41 +292,6 @@ public final class SubtypeLocaleUtils {
return keyboardLayoutSet;
}
- // InputMethodSubtype's display name for spacebar text in its locale.
- // isAdditionalSubtype (T=true, F=false)
- // locale layout | Middle Full
- // ------ ------- - --------- ----------------------
- // en_US qwerty F English English (US) exception
- // en_GB qwerty F English English (UK) exception
- // es_US spanish F Español Español (EE.UU.) exception
- // fr azerty F Français Français
- // fr_CA qwerty F Français Français (Canada)
- // fr_CH swiss F Français Français (Suisse)
- // de qwertz F Deutsch Deutsch
- // de_CH swiss T Deutsch Deutsch (Schweiz)
- // zz qwerty F QWERTY QWERTY
- // fr qwertz T Français Français
- // de qwerty T Deutsch Deutsch
- // en_US azerty T English English (US)
- // zz azerty T AZERTY AZERTY
-
- // Get InputMethodSubtype's full display name in its locale.
- public static String getFullDisplayName(final InputMethodSubtype subtype) {
- if (isNoLanguage(subtype)) {
- return getKeyboardLayoutSetDisplayName(subtype);
- }
- return getSubtypeLocaleDisplayName(subtype.getLocale());
- }
-
- // Get InputMethodSubtype's middle display name in its locale.
- public static String getMiddleDisplayName(final InputMethodSubtype subtype) {
- if (isNoLanguage(subtype)) {
- return getKeyboardLayoutSetDisplayName(subtype);
- }
- final Locale locale = getSubtypeLocale(subtype);
- return getSubtypeLocaleDisplayName(locale.getLanguage());
- }
-
// TODO: Get this information from the framework instead of maintaining here by ourselves.
// Sorted list of known Right-To-Left language codes.
private static final String[] SORTED_RTL_LANGUAGES = {
diff --git a/native/jni/src/suggest/core/result/suggestions_output_utils.cpp b/native/jni/src/suggest/core/result/suggestions_output_utils.cpp
index d07f5ca41..83140f1ab 100644
--- a/native/jni/src/suggest/core/result/suggestions_output_utils.cpp
+++ b/native/jni/src/suggest/core/result/suggestions_output_utils.cpp
@@ -17,11 +17,11 @@
#include "suggest/core/result/suggestions_output_utils.h"
#include <algorithm>
+#include <vector>
#include "suggest/core/dicnode/dic_node.h"
#include "suggest/core/dicnode/dic_node_utils.h"
#include "suggest/core/dictionary/binary_dictionary_shortcut_iterator.h"
-#include "suggest/core/dictionary/dictionary.h"
#include "suggest/core/dictionary/error_type_utils.h"
#include "suggest/core/policy/scoring.h"
#include "suggest/core/result/suggestion_results.h"
@@ -31,110 +31,113 @@ namespace latinime {
const int SuggestionsOutputUtils::MIN_LEN_FOR_MULTI_WORD_AUTOCORRECT = 16;
-// TODO: Split this method.
/* static */ void SuggestionsOutputUtils::outputSuggestions(
const Scoring *const scoringPolicy, DicTraverseSession *traverseSession,
SuggestionResults *const outSuggestionResults) {
#if DEBUG_EVALUATE_MOST_PROBABLE_STRING
const int terminalSize = 0;
#else
- const int terminalSize = std::min(MAX_RESULTS,
- static_cast<int>(traverseSession->getDicTraverseCache()->terminalSize()));
+ const int terminalSize = traverseSession->getDicTraverseCache()->terminalSize();
#endif
- DicNode terminals[MAX_RESULTS]; // Avoiding non-POD variable length array
-
+ std::vector<DicNode> terminals(terminalSize);
for (int index = terminalSize - 1; index >= 0; --index) {
traverseSession->getDicTraverseCache()->popTerminal(&terminals[index]);
}
const float languageWeight = scoringPolicy->getAdjustedLanguageWeight(
- traverseSession, terminals, terminalSize);
+ traverseSession, terminals.data(), terminalSize);
// Force autocorrection for obvious long multi-word suggestions when the top suggestion is
// a long multiple words suggestion.
// TODO: Implement a smarter auto-commit method for handling multi-word suggestions.
- // traverseSession->isPartiallyCommited() always returns false because we never auto partial
- // commit for now.
- const bool forceCommitMultiWords = (terminalSize > 0) ?
- scoringPolicy->autoCorrectsToMultiWordSuggestionIfTop()
- && (traverseSession->isPartiallyCommited()
- || (traverseSession->getInputSize()
- >= MIN_LEN_FOR_MULTI_WORD_AUTOCORRECT
- && terminals[0].hasMultipleWords())) : false;
+ const bool forceCommitMultiWords = scoringPolicy->autoCorrectsToMultiWordSuggestionIfTop()
+ && (traverseSession->getInputSize() >= MIN_LEN_FOR_MULTI_WORD_AUTOCORRECT
+ && !terminals.empty() && terminals.front().hasMultipleWords());
// TODO: have partial commit work even with multiple pointers.
const bool outputSecondWordFirstLetterInputIndex =
traverseSession->isOnlyOnePointerUsed(0 /* pointerId */);
const bool boostExactMatches = traverseSession->getDictionaryStructurePolicy()->
getHeaderStructurePolicy()->shouldBoostExactMatches();
- int codePoints[MAX_WORD_LENGTH];
// Output suggestion results here
- for (int terminalIndex = 0; terminalIndex < terminalSize; ++terminalIndex) {
- DicNode *terminalDicNode = &terminals[terminalIndex];
- if (DEBUG_GEO_FULL) {
- terminalDicNode->dump("OUT:");
- }
- const float doubleLetterCost =
- scoringPolicy->getDoubleLetterDemotionDistanceCost(terminalDicNode);
- const float compoundDistance = terminalDicNode->getCompoundDistance(languageWeight)
- + doubleLetterCost;
- const bool isPossiblyOffensiveWord =
- traverseSession->getDictionaryStructurePolicy()->getProbability(
- terminalDicNode->getProbability(), NOT_A_PROBABILITY) <= 0;
- const bool isExactMatch =
- ErrorTypeUtils::isExactMatch(terminalDicNode->getContainedErrorTypes());
- const bool isFirstCharUppercase = terminalDicNode->isFirstCharUppercase();
- // Heuristic: We exclude probability=0 first-char-uppercase words from exact match.
- // (e.g. "AMD" and "and")
- const bool isSafeExactMatch = isExactMatch
- && !(isPossiblyOffensiveWord && isFirstCharUppercase);
- const int outputTypeFlags =
- (isPossiblyOffensiveWord ? Dictionary::KIND_FLAG_POSSIBLY_OFFENSIVE : 0)
- | ((isSafeExactMatch && boostExactMatches) ? Dictionary::KIND_FLAG_EXACT_MATCH : 0);
-
- // Entries that are blacklisted or do not represent a word should not be output.
- const bool isValidWord = !terminalDicNode->isBlacklistedOrNotAWord();
-
- // Increase output score of top typing suggestion to ensure autocorrection.
- // TODO: Better integration with java side autocorrection logic.
- const int finalScore = scoringPolicy->calculateFinalScore(
- compoundDistance, traverseSession->getInputSize(),
- terminalDicNode->getContainedErrorTypes(),
- (forceCommitMultiWords && terminalDicNode->hasMultipleWords())
- || (isValidWord && scoringPolicy->doesAutoCorrectValidWord()),
- boostExactMatches);
-
- // Don't output invalid words. However, we still need to submit their shortcuts if any.
- if (isValidWord) {
- terminalDicNode->outputResult(codePoints);
- const int indexToPartialCommit = outputSecondWordFirstLetterInputIndex ?
- terminalDicNode->getSecondWordFirstInputIndex(
- traverseSession->getProximityInfoState(0)) :
- NOT_AN_INDEX;
- outSuggestionResults->addSuggestion(codePoints,
- terminalDicNode->getTotalNodeCodePointCount(),
- finalScore, Dictionary::KIND_CORRECTION | outputTypeFlags,
- indexToPartialCommit, computeFirstWordConfidence(terminalDicNode));
- }
-
- if (!terminalDicNode->hasMultipleWords()) {
- BinaryDictionaryShortcutIterator shortcutIt(
- traverseSession->getDictionaryStructurePolicy()->getShortcutsStructurePolicy(),
- traverseSession->getDictionaryStructurePolicy()
- ->getShortcutPositionOfPtNode(terminalDicNode->getPtNodePos()));
- // Shortcut is not supported for multiple words suggestions.
- // TODO: Check shortcuts during traversal for multiple words suggestions.
- const bool sameAsTyped = scoringPolicy->sameAsTyped(traverseSession, terminalDicNode);
- const int shortcutBaseScore = scoringPolicy->doesAutoCorrectValidWord() ?
- scoringPolicy->calculateFinalScore(compoundDistance,
- traverseSession->getInputSize(),
- terminalDicNode->getContainedErrorTypes(),
- true /* forceCommit */, boostExactMatches) : finalScore;
- outputShortcuts(&shortcutIt, shortcutBaseScore, sameAsTyped, outSuggestionResults);
- }
+ for (auto &terminalDicNode : terminals) {
+ outputSuggestionsOfDicNode(scoringPolicy, traverseSession, &terminalDicNode,
+ languageWeight, boostExactMatches, forceCommitMultiWords,
+ outputSecondWordFirstLetterInputIndex, outSuggestionResults);
}
scoringPolicy->getMostProbableString(traverseSession, languageWeight, outSuggestionResults);
}
+/* static */ void SuggestionsOutputUtils::outputSuggestionsOfDicNode(
+ const Scoring *const scoringPolicy, DicTraverseSession *traverseSession,
+ const DicNode *const terminalDicNode, const float languageWeight,
+ const bool boostExactMatches, const bool forceCommitMultiWords,
+ const bool outputSecondWordFirstLetterInputIndex,
+ SuggestionResults *const outSuggestionResults) {
+ if (DEBUG_GEO_FULL) {
+ terminalDicNode->dump("OUT:");
+ }
+ const float doubleLetterCost =
+ scoringPolicy->getDoubleLetterDemotionDistanceCost(terminalDicNode);
+ const float compoundDistance = terminalDicNode->getCompoundDistance(languageWeight)
+ + doubleLetterCost;
+ const bool isPossiblyOffensiveWord =
+ traverseSession->getDictionaryStructurePolicy()->getProbability(
+ terminalDicNode->getProbability(), NOT_A_PROBABILITY) <= 0;
+ const bool isExactMatch =
+ ErrorTypeUtils::isExactMatch(terminalDicNode->getContainedErrorTypes());
+ const bool isFirstCharUppercase = terminalDicNode->isFirstCharUppercase();
+ // Heuristic: We exclude probability=0 first-char-uppercase words from exact match.
+ // (e.g. "AMD" and "and")
+ const bool isSafeExactMatch = isExactMatch
+ && !(isPossiblyOffensiveWord && isFirstCharUppercase);
+ const int outputTypeFlags =
+ (isPossiblyOffensiveWord ? Dictionary::KIND_FLAG_POSSIBLY_OFFENSIVE : 0)
+ | ((isSafeExactMatch && boostExactMatches) ? Dictionary::KIND_FLAG_EXACT_MATCH : 0);
+
+ // Entries that are blacklisted or do not represent a word should not be output.
+ const bool isValidWord = !terminalDicNode->isBlacklistedOrNotAWord();
+
+ // Increase output score of top typing suggestion to ensure autocorrection.
+ // TODO: Better integration with java side autocorrection logic.
+ const int finalScore = scoringPolicy->calculateFinalScore(
+ compoundDistance, traverseSession->getInputSize(),
+ terminalDicNode->getContainedErrorTypes(),
+ (forceCommitMultiWords && terminalDicNode->hasMultipleWords())
+ || (isValidWord && scoringPolicy->doesAutoCorrectValidWord()),
+ boostExactMatches);
+
+ // Don't output invalid words. However, we still need to submit their shortcuts if any.
+ if (isValidWord) {
+ int codePoints[MAX_WORD_LENGTH];
+ terminalDicNode->outputResult(codePoints);
+ const int indexToPartialCommit = outputSecondWordFirstLetterInputIndex ?
+ terminalDicNode->getSecondWordFirstInputIndex(
+ traverseSession->getProximityInfoState(0)) :
+ NOT_AN_INDEX;
+ outSuggestionResults->addSuggestion(codePoints,
+ terminalDicNode->getTotalNodeCodePointCount(),
+ finalScore, Dictionary::KIND_CORRECTION | outputTypeFlags,
+ indexToPartialCommit, computeFirstWordConfidence(terminalDicNode));
+ }
+
+ // Output shortcuts.
+ // Shortcut is not supported for multiple words suggestions.
+ // TODO: Check shortcuts during traversal for multiple words suggestions.
+ if (!terminalDicNode->hasMultipleWords()) {
+ BinaryDictionaryShortcutIterator shortcutIt(
+ traverseSession->getDictionaryStructurePolicy()->getShortcutsStructurePolicy(),
+ traverseSession->getDictionaryStructurePolicy()
+ ->getShortcutPositionOfPtNode(terminalDicNode->getPtNodePos()));
+ const bool sameAsTyped = scoringPolicy->sameAsTyped(traverseSession, terminalDicNode);
+ const int shortcutBaseScore = scoringPolicy->doesAutoCorrectValidWord() ?
+ scoringPolicy->calculateFinalScore(compoundDistance,
+ traverseSession->getInputSize(),
+ terminalDicNode->getContainedErrorTypes(),
+ true /* forceCommit */, boostExactMatches) : finalScore;
+ outputShortcuts(&shortcutIt, shortcutBaseScore, sameAsTyped, outSuggestionResults);
+ }
+}
+
/* static */ int SuggestionsOutputUtils::computeFirstWordConfidence(
const DicNode *const terminalDicNode) {
// Get the number of spaces in the first suggestion
diff --git a/native/jni/src/suggest/core/result/suggestions_output_utils.h b/native/jni/src/suggest/core/result/suggestions_output_utils.h
index 26d4b4012..73cdb9561 100644
--- a/native/jni/src/suggest/core/result/suggestions_output_utils.h
+++ b/native/jni/src/suggest/core/result/suggestions_output_utils.h
@@ -41,11 +41,15 @@ class SuggestionsOutputUtils {
// Inputs longer than this will autocorrect if the suggestion is multi-word
static const int MIN_LEN_FOR_MULTI_WORD_AUTOCORRECT;
- static int computeFirstWordConfidence(const DicNode *const terminalDicNode);
-
+ static void outputSuggestionsOfDicNode(const Scoring *const scoringPolicy,
+ DicTraverseSession *traverseSession, const DicNode *const terminalDicNode,
+ const float languageWeight, const bool boostExactMatches,
+ const bool forceCommitMultiWords, const bool outputSecondWordFirstLetterInputIndex,
+ SuggestionResults *const outSuggestionResults);
static void outputShortcuts(BinaryDictionaryShortcutIterator *const shortcutIt,
const int finalScore, const bool sameAsTyped,
SuggestionResults *const outSuggestionResults);
+ static int computeFirstWordConfidence(const DicNode *const terminalDicNode);
};
} // namespace latinime
#endif // LATINIME_SUGGESTIONS_OUTPUT_UTILS
diff --git a/native/jni/src/suggest/core/session/dic_traverse_session.cpp b/native/jni/src/suggest/core/session/dic_traverse_session.cpp
index 5070491f4..77b634e07 100644
--- a/native/jni/src/suggest/core/session/dic_traverse_session.cpp
+++ b/native/jni/src/suggest/core/session/dic_traverse_session.cpp
@@ -68,7 +68,6 @@ void DicTraverseSession::resetCache(const int thresholdForNextActiveDicNodes, co
mDicNodesCache.reset(thresholdForNextActiveDicNodes /* nextActiveSize */,
maxWords /* terminalSize */);
mMultiBigramMap.clear();
- mPartiallyCommited = false;
}
void DicTraverseSession::initializeProximityInfoStates(const int *const inputCodePoints,
diff --git a/native/jni/src/suggest/core/session/dic_traverse_session.h b/native/jni/src/suggest/core/session/dic_traverse_session.h
index b718fb57a..9e5d902dd 100644
--- a/native/jni/src/suggest/core/session/dic_traverse_session.h
+++ b/native/jni/src/suggest/core/session/dic_traverse_session.h
@@ -61,7 +61,7 @@ class DicTraverseSession {
AK_FORCE_INLINE DicTraverseSession(JNIEnv *env, jstring localeStr, bool usesLargeCache)
: mPrevWordPtNodePos(NOT_A_DICT_POS), mProximityInfo(nullptr),
mDictionary(nullptr), mSuggestOptions(nullptr), mDicNodesCache(usesLargeCache),
- mMultiBigramMap(), mInputSize(0), mPartiallyCommited(false), mMaxPointerCount(1),
+ mMultiBigramMap(), mInputSize(0), mMaxPointerCount(1),
mMultiWordCostMultiplier(1.0f) {
// NOTE: mProximityInfoStates is an array of instances.
// No need to initialize it explicitly here.
@@ -95,8 +95,6 @@ class DicTraverseSession {
return &mProximityInfoStates[id];
}
int getInputSize() const { return mInputSize; }
- void setPartiallyCommited() { mPartiallyCommited = true; }
- bool isPartiallyCommited() const { return mPartiallyCommited; }
bool isOnlyOnePointerUsed(int *pointerId) const {
// Not in the dictionary word
@@ -188,7 +186,6 @@ class DicTraverseSession {
ProximityInfoState mProximityInfoStates[MAX_POINTER_COUNT_G];
int mInputSize;
- bool mPartiallyCommited;
int mMaxPointerCount;
/////////////////////////////////
diff --git a/tests/src/com/android/inputmethod/latin/utils/SpacebarLanguagetUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/SpacebarLanguagetUtilsTests.java
new file mode 100644
index 000000000..ff1103e4f
--- /dev/null
+++ b/tests/src/com/android/inputmethod/latin/utils/SpacebarLanguagetUtilsTests.java
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.latin.utils;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.inputmethod.InputMethodInfo;
+import android.view.inputmethod.InputMethodSubtype;
+
+import com.android.inputmethod.latin.RichInputMethodManager;
+
+import java.util.ArrayList;
+import java.util.Locale;
+
+@SmallTest
+public class SpacebarLanguagetUtilsTests extends AndroidTestCase {
+ // All input method subtypes of LatinIME.
+ private final ArrayList<InputMethodSubtype> mSubtypesList = CollectionUtils.newArrayList();
+
+ private RichInputMethodManager mRichImm;
+ private Resources mRes;
+
+ InputMethodSubtype EN_US;
+ InputMethodSubtype EN_GB;
+ InputMethodSubtype ES_US;
+ InputMethodSubtype FR;
+ InputMethodSubtype FR_CA;
+ InputMethodSubtype FR_CH;
+ InputMethodSubtype DE;
+ InputMethodSubtype DE_CH;
+ InputMethodSubtype ZZ;
+ InputMethodSubtype DE_QWERTY;
+ InputMethodSubtype FR_QWERTZ;
+ InputMethodSubtype EN_US_AZERTY;
+ InputMethodSubtype EN_UK_DVORAK;
+ InputMethodSubtype ES_US_COLEMAK;
+ InputMethodSubtype ZZ_AZERTY;
+ InputMethodSubtype ZZ_PC;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ final Context context = getContext();
+ RichInputMethodManager.init(context);
+ mRichImm = RichInputMethodManager.getInstance();
+ mRes = context.getResources();
+ SubtypeLocaleUtils.init(context);
+
+ final InputMethodInfo imi = mRichImm.getInputMethodInfoOfThisIme();
+ final int subtypeCount = imi.getSubtypeCount();
+ for (int index = 0; index < subtypeCount; index++) {
+ final InputMethodSubtype subtype = imi.getSubtypeAt(index);
+ mSubtypesList.add(subtype);
+ }
+
+ EN_US = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
+ Locale.US.toString(), "qwerty");
+ EN_GB = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
+ Locale.UK.toString(), "qwerty");
+ ES_US = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
+ "es_US", "spanish");
+ FR = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
+ Locale.FRENCH.toString(), "azerty");
+ FR_CA = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
+ Locale.CANADA_FRENCH.toString(), "qwerty");
+ FR_CH = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
+ "fr_CH", "swiss");
+ DE = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
+ Locale.GERMAN.toString(), "qwertz");
+ DE_CH = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
+ "de_CH", "swiss");
+ ZZ = mRichImm.findSubtypeByLocaleAndKeyboardLayoutSet(
+ SubtypeLocaleUtils.NO_LANGUAGE, "qwerty");
+ DE_QWERTY = AdditionalSubtypeUtils.createAdditionalSubtype(
+ Locale.GERMAN.toString(), "qwerty", null);
+ FR_QWERTZ = AdditionalSubtypeUtils.createAdditionalSubtype(
+ Locale.FRENCH.toString(), "qwertz", null);
+ EN_US_AZERTY = AdditionalSubtypeUtils.createAdditionalSubtype(
+ Locale.US.toString(), "azerty", null);
+ EN_UK_DVORAK = AdditionalSubtypeUtils.createAdditionalSubtype(
+ Locale.UK.toString(), "dvorak", null);
+ ES_US_COLEMAK = AdditionalSubtypeUtils.createAdditionalSubtype(
+ "es_US", "colemak", null);
+ ZZ_AZERTY = AdditionalSubtypeUtils.createAdditionalSubtype(
+ SubtypeLocaleUtils.NO_LANGUAGE, "azerty", null);
+ ZZ_PC = AdditionalSubtypeUtils.createAdditionalSubtype(
+ SubtypeLocaleUtils.NO_LANGUAGE, "pcqwerty", null);
+ }
+
+ public void testAllFullDisplayNameForSpacebar() {
+ for (final InputMethodSubtype subtype : mSubtypesList) {
+ final String subtypeName = SubtypeLocaleUtils
+ .getSubtypeDisplayNameInSystemLocale(subtype);
+ final String spacebarText = SpacebarLanguageUtils.getFullDisplayName(subtype);
+ final String languageName = SubtypeLocaleUtils
+ .getSubtypeLocaleDisplayName(subtype.getLocale());
+ if (SubtypeLocaleUtils.isNoLanguage(subtype)) {
+ assertFalse(subtypeName, spacebarText.contains(languageName));
+ } else {
+ assertTrue(subtypeName, spacebarText.contains(languageName));
+ }
+ }
+ }
+
+ public void testAllMiddleDisplayNameForSpacebar() {
+ for (final InputMethodSubtype subtype : mSubtypesList) {
+ final String subtypeName = SubtypeLocaleUtils
+ .getSubtypeDisplayNameInSystemLocale(subtype);
+ final String spacebarText = SpacebarLanguageUtils.getMiddleDisplayName(subtype);
+ if (SubtypeLocaleUtils.isNoLanguage(subtype)) {
+ assertEquals(subtypeName,
+ SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(subtype), spacebarText);
+ } else {
+ final Locale locale = SubtypeLocaleUtils.getSubtypeLocale(subtype);
+ assertEquals(subtypeName,
+ SubtypeLocaleUtils.getSubtypeLocaleDisplayName(locale.getLanguage()),
+ spacebarText);
+ }
+ }
+ }
+
+ // InputMethodSubtype's display name for spacebar text in its locale.
+ // isAdditionalSubtype (T=true, F=false)
+ // locale layout | Middle Full
+ // ------ ------- - --------- ----------------------
+ // en_US qwerty F English English (US) exception
+ // en_GB qwerty F English English (UK) exception
+ // es_US spanish F Español Español (EE.UU.) exception
+ // fr azerty F Français Français
+ // fr_CA qwerty F Français Français (Canada)
+ // fr_CH swiss F Français Français (Suisse)
+ // de qwertz F Deutsch Deutsch
+ // de_CH swiss F Deutsch Deutsch (Schweiz)
+ // zz qwerty F QWERTY QWERTY
+ // fr qwertz T Français Français
+ // de qwerty T Deutsch Deutsch
+ // en_US azerty T English English (US)
+ // zz azerty T AZERTY AZERTY
+
+ private final RunInLocale<Void> testsPredefinedSubtypesForSpacebar = new RunInLocale<Void>() {
+ @Override
+ protected Void job(final Resources res) {
+ assertEquals("en_US", "English (US)",
+ SpacebarLanguageUtils.getFullDisplayName(EN_US));
+ assertEquals("en_GB", "English (UK)",
+ SpacebarLanguageUtils.getFullDisplayName(EN_GB));
+ assertEquals("es_US", "Español (EE.UU.)",
+ SpacebarLanguageUtils.getFullDisplayName(ES_US));
+ assertEquals("fr", "Français",
+ SpacebarLanguageUtils.getFullDisplayName(FR));
+ assertEquals("fr_CA", "Français (Canada)",
+ SpacebarLanguageUtils.getFullDisplayName(FR_CA));
+ assertEquals("fr_CH", "Français (Suisse)",
+ SpacebarLanguageUtils.getFullDisplayName(FR_CH));
+ assertEquals("de", "Deutsch",
+ SpacebarLanguageUtils.getFullDisplayName(DE));
+ assertEquals("de_CH", "Deutsch (Schweiz)",
+ SpacebarLanguageUtils.getFullDisplayName(DE_CH));
+ assertEquals("zz", "QWERTY",
+ SpacebarLanguageUtils.getFullDisplayName(ZZ));
+
+ assertEquals("en_US", "English",
+ SpacebarLanguageUtils.getMiddleDisplayName(EN_US));
+ assertEquals("en_GB", "English",
+ SpacebarLanguageUtils.getMiddleDisplayName(EN_GB));
+ assertEquals("es_US", "Español",
+ SpacebarLanguageUtils.getMiddleDisplayName(ES_US));
+ assertEquals("fr", "Français",
+ SpacebarLanguageUtils.getMiddleDisplayName(FR));
+ assertEquals("fr_CA", "Français",
+ SpacebarLanguageUtils.getMiddleDisplayName(FR_CA));
+ assertEquals("fr_CH", "Français",
+ SpacebarLanguageUtils.getMiddleDisplayName(FR_CH));
+ assertEquals("de", "Deutsch",
+ SpacebarLanguageUtils.getMiddleDisplayName(DE));
+ assertEquals("de_CH", "Deutsch",
+ SpacebarLanguageUtils.getMiddleDisplayName(DE_CH));
+ assertEquals("zz", "QWERTY",
+ SpacebarLanguageUtils.getMiddleDisplayName(ZZ));
+ return null;
+ }
+ };
+
+ private final RunInLocale<Void> testsAdditionalSubtypesForSpacebar = new RunInLocale<Void>() {
+ @Override
+ protected Void job(final Resources res) {
+ assertEquals("fr qwertz", "Français",
+ SpacebarLanguageUtils.getFullDisplayName(FR_QWERTZ));
+ assertEquals("de qwerty", "Deutsch",
+ SpacebarLanguageUtils.getFullDisplayName(DE_QWERTY));
+ assertEquals("en_US azerty", "English (US)",
+ SpacebarLanguageUtils.getFullDisplayName(EN_US_AZERTY));
+ assertEquals("en_UK dvorak", "English (UK)",
+ SpacebarLanguageUtils.getFullDisplayName(EN_UK_DVORAK));
+ assertEquals("es_US colemak", "Español (EE.UU.)",
+ SpacebarLanguageUtils.getFullDisplayName(ES_US_COLEMAK));
+ assertEquals("zz azerty", "AZERTY",
+ SpacebarLanguageUtils.getFullDisplayName(ZZ_AZERTY));
+ assertEquals("zz pc", "PC",
+ SpacebarLanguageUtils.getFullDisplayName(ZZ_PC));
+
+ assertEquals("fr qwertz", "Français",
+ SpacebarLanguageUtils.getMiddleDisplayName(FR_QWERTZ));
+ assertEquals("de qwerty", "Deutsch",
+ SpacebarLanguageUtils.getMiddleDisplayName(DE_QWERTY));
+ assertEquals("en_US azerty", "English",
+ SpacebarLanguageUtils.getMiddleDisplayName(EN_US_AZERTY));
+ assertEquals("en_UK dvorak", "English",
+ SpacebarLanguageUtils.getMiddleDisplayName(EN_UK_DVORAK));
+ assertEquals("es_US colemak", "Español",
+ SpacebarLanguageUtils.getMiddleDisplayName(ES_US_COLEMAK));
+ assertEquals("zz azerty", "AZERTY",
+ SpacebarLanguageUtils.getMiddleDisplayName(ZZ_AZERTY));
+ assertEquals("zz pc", "PC",
+ SpacebarLanguageUtils.getMiddleDisplayName(ZZ_PC));
+ return null;
+ }
+ };
+
+ public void testPredefinedSubtypesForSpacebarInEnglish() {
+ testsPredefinedSubtypesForSpacebar.runInLocale(mRes, Locale.ENGLISH);
+ }
+
+ public void testAdditionalSubtypeForSpacebarInEnglish() {
+ testsAdditionalSubtypesForSpacebar.runInLocale(mRes, Locale.ENGLISH);
+ }
+
+ public void testPredefinedSubtypesForSpacebarInFrench() {
+ testsPredefinedSubtypesForSpacebar.runInLocale(mRes, Locale.FRENCH);
+ }
+
+ public void testAdditionalSubtypeForSpacebarInFrench() {
+ testsAdditionalSubtypesForSpacebar.runInLocale(mRes, Locale.FRENCH);
+ }
+}
diff --git a/tests/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtilsTests.java b/tests/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtilsTests.java
index eb8a61a16..ee345905c 100644
--- a/tests/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtilsTests.java
+++ b/tests/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtilsTests.java
@@ -123,12 +123,23 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
assertEquals("en_US", "qwerty", SubtypeLocaleUtils.getKeyboardLayoutSetName(EN_US));
assertEquals("en_GB", "qwerty", SubtypeLocaleUtils.getKeyboardLayoutSetName(EN_GB));
assertEquals("es_US", "spanish", SubtypeLocaleUtils.getKeyboardLayoutSetName(ES_US));
- assertEquals("fr ", "azerty", SubtypeLocaleUtils.getKeyboardLayoutSetName(FR));
+ assertEquals("fr", "azerty", SubtypeLocaleUtils.getKeyboardLayoutSetName(FR));
assertEquals("fr_CA", "qwerty", SubtypeLocaleUtils.getKeyboardLayoutSetName(FR_CA));
assertEquals("fr_CH", "swiss", SubtypeLocaleUtils.getKeyboardLayoutSetName(FR_CH));
- assertEquals("de ", "qwertz", SubtypeLocaleUtils.getKeyboardLayoutSetName(DE));
+ assertEquals("de", "qwertz", SubtypeLocaleUtils.getKeyboardLayoutSetName(DE));
assertEquals("de_CH", "swiss", SubtypeLocaleUtils.getKeyboardLayoutSetName(DE_CH));
- assertEquals("zz ", "qwerty", SubtypeLocaleUtils.getKeyboardLayoutSetName(ZZ));
+ assertEquals("zz", "qwerty", SubtypeLocaleUtils.getKeyboardLayoutSetName(ZZ));
+
+ assertEquals("de qwerty", "qwerty", SubtypeLocaleUtils.getKeyboardLayoutSetName(DE_QWERTY));
+ assertEquals("fr qwertz", "qwertz", SubtypeLocaleUtils.getKeyboardLayoutSetName(FR_QWERTZ));
+ assertEquals("en_US azerty", "azerty",
+ SubtypeLocaleUtils.getKeyboardLayoutSetName(EN_US_AZERTY));
+ assertEquals("en_UK dvorak", "dvorak",
+ SubtypeLocaleUtils.getKeyboardLayoutSetName(EN_UK_DVORAK));
+ assertEquals("es_US colemak", "colemak",
+ SubtypeLocaleUtils.getKeyboardLayoutSetName(ES_US_COLEMAK));
+ assertEquals("zz azerty", "azerty",
+ SubtypeLocaleUtils.getKeyboardLayoutSetName(ZZ_AZERTY));
}
// InputMethodSubtype's display name in system locale (en_US).
@@ -161,17 +172,17 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(EN_GB));
assertEquals("es_US", "Spanish (US)",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ES_US));
- assertEquals("fr ", "French",
+ assertEquals("fr", "French",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR));
assertEquals("fr_CA", "French (Canada)",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR_CA));
assertEquals("fr_CH", "French (Switzerland)",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR_CH));
- assertEquals("de ", "German",
+ assertEquals("de", "German",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(DE));
assertEquals("de_CH", "German (Switzerland)",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(DE_CH));
- assertEquals("zz ", "Alphabet (QWERTY)",
+ assertEquals("zz", "Alphabet (QWERTY)",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ZZ));
return null;
}
@@ -183,17 +194,19 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
final RunInLocale<Void> tests = new RunInLocale<Void>() {
@Override
protected Void job(final Resources res) {
- assertEquals("fr qwertz", "French (QWERTZ)",
+ assertEquals("fr qwertz", "French (QWERTZ)",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR_QWERTZ));
- assertEquals("de qwerty", "German (QWERTY)",
+ assertEquals("de qwerty", "German (QWERTY)",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(DE_QWERTY));
assertEquals("en_US azerty", "English (US) (AZERTY)",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(EN_US_AZERTY));
- assertEquals("en_UK dvorak", "English (UK) (Dvorak)",
+ assertEquals("en_UK dvorak","English (UK) (Dvorak)",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(EN_UK_DVORAK));
- assertEquals("es_US colemak","Spanish (US) (Colemak)",
+ assertEquals("es_US colemak", "Spanish (US) (Colemak)",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ES_US_COLEMAK));
- assertEquals("zz pc", "Alphabet (PC)",
+ assertEquals("zz azerty", "Alphabet (AZERTY)",
+ SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ZZ_AZERTY));
+ assertEquals("zz pc", "Alphabet (PC)",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ZZ_PC));
return null;
}
@@ -231,17 +244,17 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(EN_GB));
assertEquals("es_US", "Espagnol (États-Unis)",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ES_US));
- assertEquals("fr ", "Français",
+ assertEquals("fr", "Français",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR));
assertEquals("fr_CA", "Français (Canada)",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR_CA));
assertEquals("fr_CH", "Français (Suisse)",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR_CH));
- assertEquals("de ", "Allemand",
+ assertEquals("de", "Allemand",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(DE));
assertEquals("de_CH", "Allemand (Suisse)",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(DE_CH));
- assertEquals("zz ", "Alphabet latin (QWERTY)",
+ assertEquals("zz", "Alphabet latin (QWERTY)",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ZZ));
return null;
}
@@ -253,17 +266,19 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
final RunInLocale<Void> tests = new RunInLocale<Void>() {
@Override
protected Void job(final Resources res) {
- assertEquals("fr qwertz", "Français (QWERTZ)",
+ assertEquals("fr qwertz", "Français (QWERTZ)",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(FR_QWERTZ));
- assertEquals("de qwerty", "Allemand (QWERTY)",
+ assertEquals("de qwerty", "Allemand (QWERTY)",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(DE_QWERTY));
assertEquals("en_US azerty", "Anglais (États-Unis) (AZERTY)",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(EN_US_AZERTY));
assertEquals("en_UK dvorak", "Anglais (Royaume-Uni) (Dvorak)",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(EN_UK_DVORAK));
- assertEquals("es_US colemak","Espagnol (États-Unis) (Colemak)",
+ assertEquals("es_US colemak", "Espagnol (États-Unis) (Colemak)",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ES_US_COLEMAK));
- assertEquals("zz pc", "Alphabet latin (PC)",
+ assertEquals("zz azerty", "Alphabet latin (AZERTY)",
+ SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ZZ_AZERTY));
+ assertEquals("zz pc", "Alphabet latin (PC)",
SubtypeLocaleUtils.getSubtypeDisplayNameInSystemLocale(ZZ_PC));
return null;
}
@@ -271,126 +286,6 @@ public class SubtypeLocaleUtilsTests extends AndroidTestCase {
tests.runInLocale(mRes, Locale.FRENCH);
}
- public void testAllFullDisplayNameForSpacebar() {
- for (final InputMethodSubtype subtype : mSubtypesList) {
- final String subtypeName = SubtypeLocaleUtils
- .getSubtypeDisplayNameInSystemLocale(subtype);
- final String spacebarText = SubtypeLocaleUtils.getFullDisplayName(subtype);
- final String languageName = SubtypeLocaleUtils
- .getSubtypeLocaleDisplayName(subtype.getLocale());
- if (SubtypeLocaleUtils.isNoLanguage(subtype)) {
- assertFalse(subtypeName, spacebarText.contains(languageName));
- } else {
- assertTrue(subtypeName, spacebarText.contains(languageName));
- }
- }
- }
-
- public void testAllMiddleDisplayNameForSpacebar() {
- for (final InputMethodSubtype subtype : mSubtypesList) {
- final String subtypeName = SubtypeLocaleUtils
- .getSubtypeDisplayNameInSystemLocale(subtype);
- final String spacebarText = SubtypeLocaleUtils.getMiddleDisplayName(subtype);
- if (SubtypeLocaleUtils.isNoLanguage(subtype)) {
- assertEquals(subtypeName,
- SubtypeLocaleUtils.getKeyboardLayoutSetDisplayName(subtype), spacebarText);
- } else {
- final Locale locale = SubtypeLocaleUtils.getSubtypeLocale(subtype);
- assertEquals(subtypeName,
- SubtypeLocaleUtils.getSubtypeLocaleDisplayName(locale.getLanguage()),
- spacebarText);
- }
- }
- }
-
- // InputMethodSubtype's display name for spacebar text in its locale.
- // isAdditionalSubtype (T=true, F=false)
- // locale layout | Middle Full
- // ------ ------- - --------- ----------------------
- // en_US qwerty F English English (US) exception
- // en_GB qwerty F English English (UK) exception
- // es_US spanish F Español Español (EE.UU.) exception
- // fr azerty F Français Français
- // fr_CA qwerty F Français Français (Canada)
- // fr_CH swiss F Français Français (Suisse)
- // de qwertz F Deutsch Deutsch
- // de_CH swiss F Deutsch Deutsch (Schweiz)
- // zz qwerty F QWERTY QWERTY
- // fr qwertz T Français Français
- // de qwerty T Deutsch Deutsch
- // en_US azerty T English English (US)
- // zz azerty T AZERTY AZERTY
-
- private final RunInLocale<Void> testsPredefinedSubtypesForSpacebar = new RunInLocale<Void>() {
- @Override
- protected Void job(final Resources res) {
- assertEquals("en_US", "English (US)", SubtypeLocaleUtils.getFullDisplayName(EN_US));
- assertEquals("en_GB", "English (UK)", SubtypeLocaleUtils.getFullDisplayName(EN_GB));
- assertEquals("es_US", "Español (EE.UU.)",
- SubtypeLocaleUtils.getFullDisplayName(ES_US));
- assertEquals("fr ", "Français", SubtypeLocaleUtils.getFullDisplayName(FR));
- assertEquals("fr_CA", "Français (Canada)",
- SubtypeLocaleUtils.getFullDisplayName(FR_CA));
- assertEquals("fr_CH", "Français (Suisse)",
- SubtypeLocaleUtils.getFullDisplayName(FR_CH));
- assertEquals("de ", "Deutsch", SubtypeLocaleUtils.getFullDisplayName(DE));
- assertEquals("de_CH", "Deutsch (Schweiz)",
- SubtypeLocaleUtils.getFullDisplayName(DE_CH));
- assertEquals("zz ", "QWERTY", SubtypeLocaleUtils.getFullDisplayName(ZZ));
-
- assertEquals("en_US", "English", SubtypeLocaleUtils.getMiddleDisplayName(EN_US));
- assertEquals("en_GB", "English", SubtypeLocaleUtils.getMiddleDisplayName(EN_GB));
- assertEquals("es_US", "Español", SubtypeLocaleUtils.getMiddleDisplayName(ES_US));
- assertEquals("fr ", "Français", SubtypeLocaleUtils.getMiddleDisplayName(FR));
- assertEquals("fr_CA", "Français", SubtypeLocaleUtils.getMiddleDisplayName(FR_CA));
- assertEquals("fr_CH", "Français", SubtypeLocaleUtils.getMiddleDisplayName(FR_CH));
- assertEquals("de ", "Deutsch", SubtypeLocaleUtils.getMiddleDisplayName(DE));
- assertEquals("de_CH", "Deutsch", SubtypeLocaleUtils.getMiddleDisplayName(DE_CH));
- assertEquals("zz ", "QWERTY", SubtypeLocaleUtils.getMiddleDisplayName(ZZ));
- return null;
- }
- };
-
- private final RunInLocale<Void> testsAdditionalSubtypesForSpacebar = new RunInLocale<Void>() {
- @Override
- protected Void job(final Resources res) {
- assertEquals("fr qwertz", "Français",
- SubtypeLocaleUtils.getFullDisplayName(FR_QWERTZ));
- assertEquals("de qwerty", "Deutsch",
- SubtypeLocaleUtils.getFullDisplayName(DE_QWERTY));
- assertEquals("en_US azerty", "English (US)",
- SubtypeLocaleUtils.getFullDisplayName(EN_US_AZERTY));
- assertEquals("zz azerty", "AZERTY",
- SubtypeLocaleUtils.getFullDisplayName(ZZ_AZERTY));
-
- assertEquals("fr qwertz", "Français",
- SubtypeLocaleUtils.getMiddleDisplayName(FR_QWERTZ));
- assertEquals("de qwerty", "Deutsch",
- SubtypeLocaleUtils.getMiddleDisplayName(DE_QWERTY));
- assertEquals("en_US azerty", "English",
- SubtypeLocaleUtils.getMiddleDisplayName(EN_US_AZERTY));
- assertEquals("zz azerty", "AZERTY",
- SubtypeLocaleUtils.getMiddleDisplayName(ZZ_AZERTY));
- return null;
- }
- };
-
- public void testPredefinedSubtypesForSpacebarInEnglish() {
- testsPredefinedSubtypesForSpacebar.runInLocale(mRes, Locale.ENGLISH);
- }
-
- public void testAdditionalSubtypeForSpacebarInEnglish() {
- testsAdditionalSubtypesForSpacebar.runInLocale(mRes, Locale.ENGLISH);
- }
-
- public void testPredefinedSubtypesForSpacebarInFrench() {
- testsPredefinedSubtypesForSpacebar.runInLocale(mRes, Locale.FRENCH);
- }
-
- public void testAdditionalSubtypeForSpacebarInFrench() {
- testsAdditionalSubtypesForSpacebar.runInLocale(mRes, Locale.FRENCH);
- }
-
public void testIsRtlLanguage() {
// Known Right-to-Left language subtypes.
final InputMethodSubtype ARABIC = mRichImm