Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit af5fbe70 authored by Jean Chalard's avatar Jean Chalard
Browse files

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
parent 1162c053
Loading
Loading
Loading
Loading
+1 −6
Original line number Diff line number Diff line
@@ -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
+54 −0
Original line number Diff line number Diff line
@@ -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;
    }
+33 −4
Original line number Diff line number Diff line
@@ -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;
+14 −0
Original line number Diff line number Diff line
@@ -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));