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

Commit 258bfe66 authored by Yusuke Nojima's avatar Yusuke Nojima
Browse files

Classify touches into three types.

Change-Id: I7c1d42835e0c15d596a1b66d421b0aa514ec0890
parent 43149e45
Loading
Loading
Loading
Loading
+24 −20
Original line number Diff line number Diff line
@@ -31,141 +31,145 @@
            android:label="@string/subtype_en_US"
            android:imeSubtypeLocale="en_US"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="TrySuppressingImeSwitcher,AsciiCapable"
            android:imeSubtypeExtraValue="TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection"
    />
    <subtype android:icon="@drawable/ic_subtype_keyboard"
            android:label="@string/subtype_en_GB"
            android:imeSubtypeLocale="en_GB"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="TrySuppressingImeSwitcher,AsciiCapable"
            android:imeSubtypeExtraValue="TrySuppressingImeSwitcher,AsciiCapable,SupportTouchPositionCorrection"
    />
    <subtype android:icon="@drawable/ic_subtype_keyboard"
            android:label="@string/subtype_generic"
            android:imeSubtypeLocale="ar"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="SupportTouchPositionCorrection"
    />
    <subtype android:icon="@drawable/ic_subtype_keyboard"
            android:label="@string/subtype_generic"
            android:imeSubtypeLocale="cs"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="AsciiCapable"
            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
    />
    <subtype android:icon="@drawable/ic_subtype_keyboard"
            android:label="@string/subtype_generic"
            android:imeSubtypeLocale="da"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="AsciiCapable"
            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
    />
    <subtype android:icon="@drawable/ic_subtype_keyboard"
            android:label="@string/subtype_generic"
            android:imeSubtypeLocale="de"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="AsciiCapable"
            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
    />
    <subtype android:icon="@drawable/ic_subtype_keyboard"
            android:label="@string/subtype_de_qwerty"
            android:imeSubtypeLocale="de"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="AsciiCapable,KeyboardLocale=de_ZZ"
            android:imeSubtypeExtraValue="AsciiCapable,KeyboardLocale=de_ZZ,SupportTouchPositionCorrection"
    />
    <subtype android:icon="@drawable/ic_subtype_keyboard"
            android:label="@string/subtype_generic"
            android:imeSubtypeLocale="es"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="AsciiCapable"
            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
    />
    <subtype android:icon="@drawable/ic_subtype_keyboard"
            android:label="@string/subtype_generic"
            android:imeSubtypeLocale="fi"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="AsciiCapable"
            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
    />
    <subtype android:icon="@drawable/ic_subtype_keyboard"
            android:label="@string/subtype_generic"
            android:imeSubtypeLocale="fr"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="AsciiCapable"
            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
    />
    <subtype android:icon="@drawable/ic_subtype_keyboard"
            android:label="@string/subtype_generic"
            android:imeSubtypeLocale="fr_CA"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="AsciiCapable"
            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
    />
    <subtype android:icon="@drawable/ic_subtype_keyboard"
            android:label="@string/subtype_generic"
            android:imeSubtypeLocale="fr_CH"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="AsciiCapable"
            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
    />
    <subtype android:icon="@drawable/ic_subtype_keyboard"
            android:label="@string/subtype_generic"
            android:imeSubtypeLocale="hr"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="AsciiCapable"
            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
    />
    <subtype android:icon="@drawable/ic_subtype_keyboard"
            android:label="@string/subtype_generic"
            android:imeSubtypeLocale="hu"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="AsciiCapable"
            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
    />
    <subtype android:icon="@drawable/ic_subtype_keyboard"
            android:label="@string/subtype_generic"
            android:imeSubtypeLocale="it"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="AsciiCapable"
            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
    />
    <!-- Java uses the deprecated "iw" code instead of the standard "he" code for Hebrew. -->
    <subtype android:icon="@drawable/ic_subtype_keyboard"
            android:label="@string/subtype_generic"
            android:imeSubtypeLocale="iw"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="SupportTouchPositionCorrection"
    />
    <subtype android:icon="@drawable/ic_subtype_keyboard"
            android:label="@string/subtype_generic"
            android:imeSubtypeLocale="nb"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="AsciiCapable"
            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
    />
    <subtype android:icon="@drawable/ic_subtype_keyboard"
            android:label="@string/subtype_generic"
            android:imeSubtypeLocale="nl"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="AsciiCapable"
            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
    />
    <subtype android:icon="@drawable/ic_subtype_keyboard"
            android:label="@string/subtype_generic"
            android:imeSubtypeLocale="pl"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="AsciiCapable"
            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
    />
    <subtype android:icon="@drawable/ic_subtype_keyboard"
            android:label="@string/subtype_generic"
            android:imeSubtypeLocale="pt"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="AsciiCapable"
            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
    />
    <subtype android:icon="@drawable/ic_subtype_keyboard"
            android:label="@string/subtype_generic"
            android:imeSubtypeLocale="ru"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="SupportTouchPositionCorrection"
    />
    <subtype android:icon="@drawable/ic_subtype_keyboard"
            android:label="@string/subtype_generic"
            android:imeSubtypeLocale="sr"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="SupportTouchPositionCorrection"
    />
    <subtype android:icon="@drawable/ic_subtype_keyboard"
            android:label="@string/subtype_generic"
            android:imeSubtypeLocale="sv"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="AsciiCapable"
            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
    />
    <subtype android:icon="@drawable/ic_subtype_keyboard"
            android:label="@string/subtype_generic"
            android:imeSubtypeLocale="tr"
            android:imeSubtypeMode="keyboard"
            android:imeSubtypeExtraValue="AsciiCapable"
            android:imeSubtypeExtraValue="AsciiCapable,SupportTouchPositionCorrection"
    />
</input-method>
+6 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.inputmethod.keyboard;
import android.graphics.Rect;

import com.android.inputmethod.keyboard.Key;
import com.android.inputmethod.latin.SubtypeSwitcher;
import com.android.inputmethod.latin.Utils;
import com.android.inputmethod.latin.spellcheck.SpellCheckerProximityInfo;

@@ -31,6 +32,8 @@ public class ProximityInfo {
    /** Number of key widths from current touch point to search for nearest keys. */
    private static float SEARCH_DISTANCE = 1.2f;
    private static final int[] EMPTY_INT_ARRAY = new int[0];
    private static final String SUPPORT_TOUCH_POSITION_CORRECTION =
            "SupportTouchPositionCorrection";

    private final int mKeyHeight;
    private final int mGridWidth;
@@ -120,8 +123,10 @@ public class ProximityInfo {
            keyCharCodes[i] = key.mCode;
        }

        final SubtypeSwitcher switcher = SubtypeSwitcher.getInstance();
        final boolean hasTouchPositionCorrectionData =
                mTouchPositionCorrectionXs != null
                switcher.currentSubtypeContainsExtraValueKey(SUPPORT_TOUCH_POSITION_CORRECTION)
                && mTouchPositionCorrectionXs != null
                && mTouchPositionCorrectionYs != null
                && mTouchPositionCorrectionRadii != null
                && mTouchPositionCorrectionXs.length > 0
+47 −22
Original line number Diff line number Diff line
@@ -113,6 +113,9 @@ bool Correction::initProcessState(const int outputIndex) {
    mInputIndex = mCorrectionStates[outputIndex].mInputIndex;
    mNeedsToTraverseAllNodes = mCorrectionStates[outputIndex].mNeedsToTraverseAllNodes;

    mEquivalentCharStrongCount = mCorrectionStates[outputIndex].mEquivalentCharStrongCount;
    mEquivalentCharNormalCount = mCorrectionStates[outputIndex].mEquivalentCharNormalCount;
    mEquivalentCharWeakCount = mCorrectionStates[outputIndex].mEquivalentCharWeakCount;
    mProximityCount = mCorrectionStates[outputIndex].mProximityCount;
    mTransposedCount = mCorrectionStates[outputIndex].mTransposedCount;
    mExcessiveCount = mCorrectionStates[outputIndex].mExcessiveCount;
@@ -167,6 +170,9 @@ void Correction::incrementOutputIndex() {
    mCorrectionStates[mOutputIndex].mInputIndex = mInputIndex;
    mCorrectionStates[mOutputIndex].mNeedsToTraverseAllNodes = mNeedsToTraverseAllNodes;

    mCorrectionStates[mOutputIndex].mEquivalentCharStrongCount = mEquivalentCharStrongCount;
    mCorrectionStates[mOutputIndex].mEquivalentCharNormalCount = mEquivalentCharNormalCount;
    mCorrectionStates[mOutputIndex].mEquivalentCharWeakCount = mEquivalentCharWeakCount;
    mCorrectionStates[mOutputIndex].mProximityCount = mProximityCount;
    mCorrectionStates[mOutputIndex].mTransposedCount = mTransposedCount;
    mCorrectionStates[mOutputIndex].mExcessiveCount = mExcessiveCount;
@@ -208,6 +214,12 @@ Correction::CorrectionType Correction::processSkipChar(
    }
}

inline bool isEquivalentChar(ProximityInfo::ProximityType type) {
    // 'type ProximityInfo::EQUIVALENT_CHAR_WEAK' means that
    // type == ..._WEAK or type == ..._NORMAL or type == ..._STRONG.
    return type <= ProximityInfo::EQUIVALENT_CHAR_WEAK;
}

Correction::CorrectionType Correction::processCharAndCalcState(
        const int32_t c, const bool isTerminal) {
    const int correctionCount = (mSkippedCount + mExcessiveCount + mTransposedCount);
@@ -219,8 +231,9 @@ Correction::CorrectionType Correction::processCharAndCalcState(
        bool incremented = false;
        if (mLastCharExceeded && mInputIndex == mInputLength - 1) {
            // TODO: Do not check the proximity if EditDistance exceeds the threshold
            const int matchId = mProximityInfo->getMatchedProximityId(mInputIndex, c, true);
            if (matchId == ProximityInfo::SAME_OR_ACCENTED_OR_CAPITALIZED_CHAR) {
            const ProximityInfo::ProximityType matchId =
                    mProximityInfo->getMatchedProximityId(mInputIndex, c, true);
            if (isEquivalentChar(matchId)) {
                mLastCharExceeded = false;
                --mExcessiveCount;
            } else if (matchId == ProximityInfo::NEAR_PROXIMITY_CHAR) {
@@ -264,8 +277,7 @@ Correction::CorrectionType Correction::processCharAndCalcState(

    bool secondTransposing = false;
    if (mTransposedCount % 2 == 1) {
        if (mProximityInfo->getMatchedProximityId(mInputIndex - 1, c, false)
                == ProximityInfo::SAME_OR_ACCENTED_OR_CAPITALIZED_CHAR) {
        if (isEquivalentChar(mProximityInfo->getMatchedProximityId(mInputIndex - 1, c, false))) {
            ++mTransposedCount;
            secondTransposing = true;
        } else if (mCorrectionStates[mOutputIndex].mExceeding) {
@@ -286,8 +298,8 @@ Correction::CorrectionType Correction::processCharAndCalcState(

    // TODO: Change the limit if we'll allow two or more proximity chars with corrections
    const bool checkProximityChars = noCorrectionsHappenedSoFar ||  mProximityCount == 0;
    const int matchedProximityCharId = secondTransposing
            ? ProximityInfo::SAME_OR_ACCENTED_OR_CAPITALIZED_CHAR
    const ProximityInfo::ProximityType matchedProximityCharId = secondTransposing
            ? ProximityInfo::EQUIVALENT_CHAR_NORMAL
            : mProximityInfo->getMatchedProximityId(mInputIndex, c, checkProximityChars);

    if (ProximityInfo::UNRELATED_CHAR == matchedProximityCharId) {
@@ -297,19 +309,18 @@ Correction::CorrectionType Correction::processCharAndCalcState(
        // here refers to the previous state.
        if (canTryCorrection && mCorrectionStates[mOutputIndex].mProximityMatching
                && mCorrectionStates[mOutputIndex].mExceeding
                && mProximityInfo->getMatchedProximityId(mInputIndex, mWord[mOutputIndex], false)
                        == ProximityInfo::SAME_OR_ACCENTED_OR_CAPITALIZED_CHAR) {
                && isEquivalentChar(mProximityInfo->getMatchedProximityId(
                        mInputIndex, mWord[mOutputIndex], false))) {
            // Conversion p->e
            ++mExcessiveCount;
            --mProximityCount;
        } else if (mInputIndex < mInputLength - 1 && mOutputIndex > 0 && mTransposedCount > 0
                && !mCorrectionStates[mOutputIndex].mTransposing
                && mCorrectionStates[mOutputIndex - 1].mTransposing
                && mProximityInfo->getMatchedProximityId(
                        mInputIndex, mWord[mOutputIndex - 1], false)
                                == ProximityInfo::SAME_OR_ACCENTED_OR_CAPITALIZED_CHAR
                && mProximityInfo->getMatchedProximityId(mInputIndex + 1, c, false)
                        == ProximityInfo::SAME_OR_ACCENTED_OR_CAPITALIZED_CHAR) {
                && isEquivalentChar(mProximityInfo->getMatchedProximityId(
                        mInputIndex, mWord[mOutputIndex - 1], false))
                && isEquivalentChar(
                        mProximityInfo->getMatchedProximityId(mInputIndex + 1, c, false))) {
            // Conversion t->e
            // Example:
            // occaisional -> occa   sional
@@ -320,8 +331,8 @@ Correction::CorrectionType Correction::processCharAndCalcState(
        } else if (mOutputIndex > 0 && mInputIndex > 0 && mTransposedCount > 0
                && !mCorrectionStates[mOutputIndex].mTransposing
                && mCorrectionStates[mOutputIndex - 1].mTransposing
                && mProximityInfo->getMatchedProximityId(mInputIndex - 1, c, false)
                        == ProximityInfo::SAME_OR_ACCENTED_OR_CAPITALIZED_CHAR) {
                && isEquivalentChar(
                        mProximityInfo->getMatchedProximityId(mInputIndex - 1, c, false))) {
            // Conversion t->s
            // Example:
            // chcolate -> chocolate
@@ -332,8 +343,8 @@ Correction::CorrectionType Correction::processCharAndCalcState(
        } else if (canTryCorrection && mInputIndex > 0
                && mCorrectionStates[mOutputIndex].mProximityMatching
                && mCorrectionStates[mOutputIndex].mSkipping
                && mProximityInfo->getMatchedProximityId(mInputIndex - 1, c, false)
                        == ProximityInfo::SAME_OR_ACCENTED_OR_CAPITALIZED_CHAR) {
                && isEquivalentChar(
                        mProximityInfo->getMatchedProximityId(mInputIndex - 1, c, false))) {
            // Conversion p->s
            // Note: This logic tries saving cases like contrst --> contrast -- "a" is one of
            // proximity chars of "s", but it should rather be handled as a skipped char.
@@ -341,8 +352,8 @@ Correction::CorrectionType Correction::processCharAndCalcState(
            --mProximityCount;
            return processSkipChar(c, isTerminal, false);
        } else if ((mExceeding || mTransposing) && mInputIndex - 1 < mInputLength
                && mProximityInfo->getMatchedProximityId(mInputIndex + 1, c, false)
                        == ProximityInfo::SAME_OR_ACCENTED_OR_CAPITALIZED_CHAR) {
                && isEquivalentChar(
                        mProximityInfo->getMatchedProximityId(mInputIndex + 1, c, false))) {
            // 1.2. Excessive or transpose correction
            if (mTransposing) {
                ++mTransposedCount;
@@ -362,14 +373,28 @@ Correction::CorrectionType Correction::processCharAndCalcState(
            }
            return UNRELATED;
        }
    } else if (secondTransposing
            || ProximityInfo::SAME_OR_ACCENTED_OR_CAPITALIZED_CHAR == matchedProximityCharId) {
    } else if (secondTransposing) {
        // If inputIndex is greater than mInputLength, that means there is no
        // proximity chars. So, we don't need to check proximity.
        mMatching = true;
    } else if (isEquivalentChar(matchedProximityCharId)) {
        mMatching = true;
        switch (matchedProximityCharId) {
        case ProximityInfo::EQUIVALENT_CHAR_STRONG:
            ++mEquivalentCharStrongCount;
            break;
        case ProximityInfo::EQUIVALENT_CHAR_NORMAL:
            ++mEquivalentCharNormalCount;
            break;
        case ProximityInfo::EQUIVALENT_CHAR_WEAK:
            ++mEquivalentCharWeakCount;
            break;
        default:
            assert(false);
        }
    } else if (ProximityInfo::NEAR_PROXIMITY_CHAR == matchedProximityCharId) {
        mProximityMatching = true;
        incrementProximityCount();
        ++mProximityCount;
    }

    mWord[mOutputIndex] = c;
+3 −5
Original line number Diff line number Diff line
@@ -102,11 +102,6 @@ private:
    inline CorrectionType processSkipChar(
            const int32_t c, const bool isTerminal, const bool inputIndexIncremented);

    // TODO: remove
    inline void incrementProximityCount() {
        ++mProximityCount;
    }

    const int TYPED_LETTER_MULTIPLIER;
    const int FULL_WORD_MULTIPLIER;
    const ProximityInfo *mProximityInfo;
@@ -130,6 +125,9 @@ private:
    int mOutputIndex;
    int mInputIndex;

    int mEquivalentCharStrongCount;
    int mEquivalentCharNormalCount;
    int mEquivalentCharWeakCount;
    int mProximityCount;
    int mExcessiveCount;
    int mTransposedCount;
+6 −1
Original line number Diff line number Diff line
@@ -29,6 +29,9 @@ struct CorrectionState {
    uint16_t mChildCount;
    uint8_t mInputIndex;

    uint8_t mEquivalentCharStrongCount;
    uint8_t mEquivalentCharNormalCount;
    uint8_t mEquivalentCharWeakCount;
    uint8_t mProximityCount;
    uint8_t mTransposedCount;
    uint8_t mExcessiveCount;
@@ -63,7 +66,9 @@ inline static void initCorrectionState(CorrectionState *state, const int rootPos
    state->mExcessivePos = -1;
    state->mSkipPos = -1;


    state->mEquivalentCharStrongCount = 0;
    state->mEquivalentCharNormalCount = 0;
    state->mEquivalentCharWeakCount = 0;
    state->mProximityCount = 0;
    state->mTransposedCount = 0;
    state->mExcessiveCount = 0;
Loading