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: I13b629ae14755c244af2a9406a7e9b4a4a16090fmain
parent
1162c0537d
commit
af5fbe70ac
|
@ -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() {
|
private void onSettingsKeyPressed() {
|
||||||
if (isShowingOptionDialog()) return;
|
if (isShowingOptionDialog()) return;
|
||||||
showSubtypeSelectorAndSettings();
|
showSubtypeSelectorAndSettings();
|
||||||
|
@ -1989,8 +1985,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
// NOTE: isCursorTouchingWord() is a blocking IPC call, so it often takes several
|
// 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
|
// dozen milliseconds. Avoid calling it as much as possible, since we are on the UI
|
||||||
// thread here.
|
// thread here.
|
||||||
if (!isComposingWord && (isAlphabet(primaryCode)
|
if (!isComposingWord && currentSettings.isWordCodePoint(primaryCode)
|
||||||
|| currentSettings.isWordConnector(primaryCode))
|
|
||||||
&& currentSettings.isSuggestionsRequested(mDisplayOrientation) &&
|
&& currentSettings.isSuggestionsRequested(mDisplayOrientation) &&
|
||||||
!mConnection.isCursorTouchingWord(currentSettings)) {
|
!mConnection.isCursorTouchingWord(currentSettings)) {
|
||||||
// Reset entirely the composing state anyway, then start composing a new word unless
|
// Reset entirely the composing state anyway, then start composing a new word unless
|
||||||
|
|
|
@ -22,6 +22,7 @@ import android.content.res.Resources;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.inputmethod.EditorInfo;
|
import android.view.inputmethod.EditorInfo;
|
||||||
|
|
||||||
|
import com.android.inputmethod.annotations.UsedForTesting;
|
||||||
import com.android.inputmethod.keyboard.internal.KeySpecParser;
|
import com.android.inputmethod.keyboard.internal.KeySpecParser;
|
||||||
import com.android.inputmethod.latin.Dictionary;
|
import com.android.inputmethod.latin.Dictionary;
|
||||||
import com.android.inputmethod.latin.InputAttributes;
|
import com.android.inputmethod.latin.InputAttributes;
|
||||||
|
@ -170,6 +171,55 @@ public final class SettingsValues {
|
||||||
mIsInternal = Settings.isInternal(prefs);
|
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() {
|
public boolean isApplicationSpecifiedCompletionsOn() {
|
||||||
return mInputAttributes.mApplicationSpecifiedCompletionOn;
|
return mInputAttributes.mApplicationSpecifiedCompletionOn;
|
||||||
}
|
}
|
||||||
|
@ -194,6 +244,10 @@ public final class SettingsValues {
|
||||||
return Arrays.binarySearch(mWordConnectors, code) >= 0;
|
return Arrays.binarySearch(mWordConnectors, code) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isWordCodePoint(final int code) {
|
||||||
|
return Character.isLetter(code) || isWordConnector(code);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isUsuallyPrecededBySpace(final int code) {
|
public boolean isUsuallyPrecededBySpace(final int code) {
|
||||||
return Arrays.binarySearch(mSymbolsPrecededBySpace, code) >= 0;
|
return Arrays.binarySearch(mSymbolsPrecededBySpace, code) >= 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ package com.android.inputmethod.latin.utils;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import com.android.inputmethod.latin.Constants;
|
import com.android.inputmethod.latin.Constants;
|
||||||
|
import com.android.inputmethod.latin.settings.SettingsValues;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
@ -193,27 +194,55 @@ public final class StringUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isIdenticalAfterUpcase(final String text) {
|
public static boolean isIdenticalAfterUpcase(final String text) {
|
||||||
final int len = text.length();
|
final int length = text.length();
|
||||||
for (int i = 0; i < len; i = text.offsetByCodePoints(i, 1)) {
|
int i = 0;
|
||||||
|
while (i < length) {
|
||||||
final int codePoint = text.codePointAt(i);
|
final int codePoint = text.codePointAt(i);
|
||||||
if (Character.isLetter(codePoint) && !Character.isUpperCase(codePoint)) {
|
if (Character.isLetter(codePoint) && !Character.isUpperCase(codePoint)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
i += Character.charCount(codePoint);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isIdenticalAfterDowncase(final String text) {
|
public static boolean isIdenticalAfterDowncase(final String text) {
|
||||||
final int len = text.length();
|
final int length = text.length();
|
||||||
for (int i = 0; i < len; i = text.offsetByCodePoints(i, 1)) {
|
int i = 0;
|
||||||
|
while (i < length) {
|
||||||
final int codePoint = text.codePointAt(i);
|
final int codePoint = text.codePointAt(i);
|
||||||
if (Character.isLetter(codePoint) && !Character.isLowerCase(codePoint)) {
|
if (Character.isLetter(codePoint) && !Character.isLowerCase(codePoint)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
i += Character.charCount(codePoint);
|
||||||
}
|
}
|
||||||
return true;
|
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,
|
public static boolean isIdenticalAfterCapitalizeEachWord(final String text,
|
||||||
final String separators) {
|
final String separators) {
|
||||||
boolean needCapsNext = true;
|
boolean needCapsNext = true;
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
package com.android.inputmethod.latin.utils;
|
package com.android.inputmethod.latin.utils;
|
||||||
|
|
||||||
|
import com.android.inputmethod.latin.settings.SettingsValues;
|
||||||
|
|
||||||
import android.test.AndroidTestCase;
|
import android.test.AndroidTestCase;
|
||||||
import android.test.suitebuilder.annotation.SmallTest;
|
import android.test.suitebuilder.annotation.SmallTest;
|
||||||
|
|
||||||
|
@ -183,6 +185,18 @@ public class StringUtilsTests extends AndroidTestCase {
|
||||||
assertTrue(StringUtils.isIdenticalAfterDowncase(""));
|
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,
|
private static void checkCapitalize(final String src, final String dst, final String separators,
|
||||||
final Locale locale) {
|
final Locale locale) {
|
||||||
assertEquals(dst, StringUtils.capitalizeEachWord(src, separators, locale));
|
assertEquals(dst, StringUtils.capitalizeEachWord(src, separators, locale));
|
||||||
|
|
Loading…
Reference in New Issue