Add looksValidForDictionaryInsertion

...and test it.

Also at the same time, add a facility to create a SettingsValues for
test, and some minor performance improvement to surrounding
methods.

Change-Id: I13b629ae14755c244af2a9406a7e9b4a4a16090f
main
Jean Chalard 2013-08-14 17:34:25 +09:00
parent 1162c0537d
commit af5fbe70ac
4 changed files with 102 additions and 10 deletions

View File

@ -1355,10 +1355,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
}
}
private static boolean isAlphabet(final int code) {
return Character.isLetter(code);
}
private void onSettingsKeyPressed() {
if (isShowingOptionDialog()) return;
showSubtypeSelectorAndSettings();
@ -1989,8 +1985,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// NOTE: isCursorTouchingWord() is a blocking IPC call, so it often takes several
// dozen milliseconds. Avoid calling it as much as possible, since we are on the UI
// thread here.
if (!isComposingWord && (isAlphabet(primaryCode)
|| currentSettings.isWordConnector(primaryCode))
if (!isComposingWord && currentSettings.isWordCodePoint(primaryCode)
&& currentSettings.isSuggestionsRequested(mDisplayOrientation) &&
!mConnection.isCursorTouchingWord(currentSettings)) {
// Reset entirely the composing state anyway, then start composing a new word unless

View File

@ -22,6 +22,7 @@ import android.content.res.Resources;
import android.util.Log;
import android.view.inputmethod.EditorInfo;
import com.android.inputmethod.annotations.UsedForTesting;
import com.android.inputmethod.keyboard.internal.KeySpecParser;
import com.android.inputmethod.latin.Dictionary;
import com.android.inputmethod.latin.InputAttributes;
@ -170,6 +171,55 @@ public final class SettingsValues {
mIsInternal = Settings.isInternal(prefs);
}
// Only for tests
private SettingsValues(final Locale locale) {
// TODO: locale is saved, but not used yet. May have to change this if tests require.
mLocale = locale;
mDelayUpdateOldSuggestions = 0;
mSymbolsPrecededBySpace = new int[] { '(', '[', '{', '&' };
Arrays.sort(mSymbolsPrecededBySpace);
mSymbolsFollowedBySpace = new int[] { '.', ',', ';', ':', '!', '?', ')', ']', '}', '&' };
Arrays.sort(mSymbolsFollowedBySpace);
mWordConnectors = new int[] { '\'', '-' };
Arrays.sort(mWordConnectors);
final String[] suggestPuncsSpec = new String[] { "!", "?", ",", ":", ";" };
mSuggestPuncList = createSuggestPuncList(suggestPuncsSpec);
mWordSeparators = "&\t \n()[]{}*&<>+=|.,;:!?/_\"";
mHintToSaveText = "Touch again to save";
mInputAttributes = new InputAttributes(null, false /* isFullscreenMode */);
mAutoCap = true;
mVibrateOn = true;
mSoundOn = true;
mKeyPreviewPopupOn = true;
mSlidingKeyInputPreviewEnabled = true;
mVoiceMode = "0";
mIncludesOtherImesInLanguageSwitchList = false;
mShowsLanguageSwitchKey = true;
mUseContactsDict = true;
mUseDoubleSpacePeriod = true;
mBlockPotentiallyOffensive = true;
mAutoCorrectEnabled = true;
mBigramPredictionEnabled = true;
mKeyLongpressTimeout = 300;
mKeypressVibrationDuration = 5;
mKeypressSoundVolume = 1;
mKeyPreviewPopupDismissDelay = 70;
mAutoCorrectionThreshold = 1;
mVoiceKeyEnabled = true;
mVoiceKeyOnMain = true;
mGestureInputEnabled = true;
mGestureTrailEnabled = true;
mGestureFloatingPreviewTextEnabled = true;
mCorrectionEnabled = mAutoCorrectEnabled && !mInputAttributes.mInputTypeNoAutoCorrect;
mSuggestionVisibility = 0;
mIsInternal = false;
}
@UsedForTesting
public static SettingsValues makeDummySettingsValuesForTest(final Locale locale) {
return new SettingsValues(locale);
}
public boolean isApplicationSpecifiedCompletionsOn() {
return mInputAttributes.mApplicationSpecifiedCompletionOn;
}
@ -194,6 +244,10 @@ public final class SettingsValues {
return Arrays.binarySearch(mWordConnectors, code) >= 0;
}
public boolean isWordCodePoint(final int code) {
return Character.isLetter(code) || isWordConnector(code);
}
public boolean isUsuallyPrecededBySpace(final int code) {
return Arrays.binarySearch(mSymbolsPrecededBySpace, code) >= 0;
}

View File

@ -19,6 +19,7 @@ package com.android.inputmethod.latin.utils;
import android.text.TextUtils;
import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.settings.SettingsValues;
import java.util.ArrayList;
import java.util.Locale;
@ -193,27 +194,55 @@ public final class StringUtils {
}
public static boolean isIdenticalAfterUpcase(final String text) {
final int len = text.length();
for (int i = 0; i < len; i = text.offsetByCodePoints(i, 1)) {
final int length = text.length();
int i = 0;
while (i < length) {
final int codePoint = text.codePointAt(i);
if (Character.isLetter(codePoint) && !Character.isUpperCase(codePoint)) {
return false;
}
i += Character.charCount(codePoint);
}
return true;
}
public static boolean isIdenticalAfterDowncase(final String text) {
final int len = text.length();
for (int i = 0; i < len; i = text.offsetByCodePoints(i, 1)) {
final int length = text.length();
int i = 0;
while (i < length) {
final int codePoint = text.codePointAt(i);
if (Character.isLetter(codePoint) && !Character.isLowerCase(codePoint)) {
return false;
}
i += Character.charCount(codePoint);
}
return true;
}
public static boolean looksValidForDictionaryInsertion(final CharSequence text,
final SettingsValues settings) {
if (TextUtils.isEmpty(text)) return false;
final int length = text.length();
int i = 0;
int digitCount = 0;
while (i < length) {
final int codePoint = Character.codePointAt(text, i);
final int charCount = Character.charCount(codePoint);
i += charCount;
if (Character.isDigit(codePoint)) {
// Count digits: see below
digitCount += charCount;
continue;
}
if (!settings.isWordCodePoint(codePoint)) return false;
}
// We reject strings entirely comprised of digits to avoid using PIN codes or credit
// card numbers. It would come in handy for word prediction though; a good example is
// when writing one's address where the street number is usually quite discriminative,
// as well as the postal code.
return digitCount < length;
}
public static boolean isIdenticalAfterCapitalizeEachWord(final String text,
final String separators) {
boolean needCapsNext = true;

View File

@ -16,6 +16,8 @@
package com.android.inputmethod.latin.utils;
import com.android.inputmethod.latin.settings.SettingsValues;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
@ -183,6 +185,18 @@ public class StringUtilsTests extends AndroidTestCase {
assertTrue(StringUtils.isIdenticalAfterDowncase(""));
}
public void testLooksValidForDictionaryInsertion() {
final SettingsValues settings =
SettingsValues.makeDummySettingsValuesForTest(Locale.ENGLISH);
assertTrue(StringUtils.looksValidForDictionaryInsertion("aochaueo", settings));
assertFalse(StringUtils.looksValidForDictionaryInsertion("", settings));
assertTrue(StringUtils.looksValidForDictionaryInsertion("ao-ch'aueo", settings));
assertFalse(StringUtils.looksValidForDictionaryInsertion("2908743256", settings));
assertTrue(StringUtils.looksValidForDictionaryInsertion("31aochaueo", settings));
assertFalse(StringUtils.looksValidForDictionaryInsertion("akeo raeoch oerch .", settings));
assertFalse(StringUtils.looksValidForDictionaryInsertion("!!!", settings));
}
private static void checkCapitalize(final String src, final String dst, final String separators,
final Locale locale) {
assertEquals(dst, StringUtils.capitalizeEachWord(src, separators, locale));