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

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

Limit recapitalization for reasonable performance.

At 100k text, it's reasonably fast (less than 1s on latest hardware).

Bug: 12913404
Change-Id: I426b918b2610af24364934a1c37a7314f1142ad0
parent 6fe326ae
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -158,6 +158,10 @@ public final class Constants {
    // A hint on how many characters to cache from the TextView. A good value of this is given by
    // how many characters we need to be able to almost always find the caps mode.
    public static final int EDITOR_CONTENTS_CACHE_SIZE = 1024;
    // How many characters we accept for the recapitalization functionality. This needs to be
    // large enough for all reasonable purposes, but avoid purposeful attacks. 100k sounds about
    // right for this.
    public static final int MAX_CHARACTERS_FOR_RECAPITALIZATION = 1024 * 100;

    // Must be equal to MAX_WORD_LENGTH in native/jni/src/defines.h
    public static final int DICTIONARY_MAX_WORD_LENGTH = 48;
+12 −9
Original line number Diff line number Diff line
@@ -1139,15 +1139,21 @@ public final class InputLogic {
        if (!mConnection.hasSelection()) {
            return; // No selection
        }
        final int selectionStart = mConnection.getExpectedSelectionStart();
        final int selectionEnd = mConnection.getExpectedSelectionEnd();
        final int numCharsSelected = selectionEnd - selectionStart;
        if (numCharsSelected > Constants.MAX_CHARACTERS_FOR_RECAPITALIZATION) {
            // We bail out if we have too many characters for performance reasons. We don't want
            // to suck possibly multiple-megabyte data.
            return;
        }
        // If we have a recapitalize in progress, use it; otherwise, create a new one.
        if (!mRecapitalizeStatus.isActive()
                || !mRecapitalizeStatus.isSetAt(mConnection.getExpectedSelectionStart(),
                        mConnection.getExpectedSelectionEnd())) {
                || !mRecapitalizeStatus.isSetAt(selectionStart, selectionEnd)) {
            final CharSequence selectedText =
                    mConnection.getSelectedText(0 /* flags, 0 for no styles */);
            if (TextUtils.isEmpty(selectedText)) return; // Race condition with the input connection
            mRecapitalizeStatus.initialize(mConnection.getExpectedSelectionStart(),
                    mConnection.getExpectedSelectionEnd(), selectedText.toString(),
            mRecapitalizeStatus.initialize(selectionStart, selectionEnd, selectedText.toString(),
                    settingsValues.mLocale,
                    settingsValues.mSpacingAndPunctuations.mSortedWordSeparators);
            // We trim leading and trailing whitespace.
@@ -1155,11 +1161,8 @@ public final class InputLogic {
        }
        mConnection.finishComposingText();
        mRecapitalizeStatus.rotate();
        final int numCharsDeleted = mConnection.getExpectedSelectionEnd()
                - mConnection.getExpectedSelectionStart();
        mConnection.setSelection(mConnection.getExpectedSelectionEnd(),
                mConnection.getExpectedSelectionEnd());
        mConnection.deleteSurroundingText(numCharsDeleted, 0);
        mConnection.setSelection(selectionEnd, selectionEnd);
        mConnection.deleteSurroundingText(numCharsSelected, 0);
        mConnection.commitText(mRecapitalizeStatus.getRecapitalizedString(), 0);
        mConnection.setSelection(mRecapitalizeStatus.getNewCursorStart(),
                mRecapitalizeStatus.getNewCursorEnd());