Limit recapitalization for reasonable performance.

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

Bug: 12913404
Change-Id: I426b918b2610af24364934a1c37a7314f1142ad0
This commit is contained in:
Jean Chalard 2014-05-30 14:32:57 +09:00
parent 6fe326ae42
commit fa0e76dde6
2 changed files with 16 additions and 9 deletions

View file

@ -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 // 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. // how many characters we need to be able to almost always find the caps mode.
public static final int EDITOR_CONTENTS_CACHE_SIZE = 1024; 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 // Must be equal to MAX_WORD_LENGTH in native/jni/src/defines.h
public static final int DICTIONARY_MAX_WORD_LENGTH = 48; public static final int DICTIONARY_MAX_WORD_LENGTH = 48;

View file

@ -1139,15 +1139,21 @@ public final class InputLogic {
if (!mConnection.hasSelection()) { if (!mConnection.hasSelection()) {
return; // No selection 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 we have a recapitalize in progress, use it; otherwise, create a new one.
if (!mRecapitalizeStatus.isActive() if (!mRecapitalizeStatus.isActive()
|| !mRecapitalizeStatus.isSetAt(mConnection.getExpectedSelectionStart(), || !mRecapitalizeStatus.isSetAt(selectionStart, selectionEnd)) {
mConnection.getExpectedSelectionEnd())) {
final CharSequence selectedText = final CharSequence selectedText =
mConnection.getSelectedText(0 /* flags, 0 for no styles */); mConnection.getSelectedText(0 /* flags, 0 for no styles */);
if (TextUtils.isEmpty(selectedText)) return; // Race condition with the input connection if (TextUtils.isEmpty(selectedText)) return; // Race condition with the input connection
mRecapitalizeStatus.initialize(mConnection.getExpectedSelectionStart(), mRecapitalizeStatus.initialize(selectionStart, selectionEnd, selectedText.toString(),
mConnection.getExpectedSelectionEnd(), selectedText.toString(),
settingsValues.mLocale, settingsValues.mLocale,
settingsValues.mSpacingAndPunctuations.mSortedWordSeparators); settingsValues.mSpacingAndPunctuations.mSortedWordSeparators);
// We trim leading and trailing whitespace. // We trim leading and trailing whitespace.
@ -1155,11 +1161,8 @@ public final class InputLogic {
} }
mConnection.finishComposingText(); mConnection.finishComposingText();
mRecapitalizeStatus.rotate(); mRecapitalizeStatus.rotate();
final int numCharsDeleted = mConnection.getExpectedSelectionEnd() mConnection.setSelection(selectionEnd, selectionEnd);
- mConnection.getExpectedSelectionStart(); mConnection.deleteSurroundingText(numCharsSelected, 0);
mConnection.setSelection(mConnection.getExpectedSelectionEnd(),
mConnection.getExpectedSelectionEnd());
mConnection.deleteSurroundingText(numCharsDeleted, 0);
mConnection.commitText(mRecapitalizeStatus.getRecapitalizedString(), 0); mConnection.commitText(mRecapitalizeStatus.getRecapitalizedString(), 0);
mConnection.setSelection(mRecapitalizeStatus.getNewCursorStart(), mConnection.setSelection(mRecapitalizeStatus.getNewCursorStart(),
mRecapitalizeStatus.getNewCursorEnd()); mRecapitalizeStatus.getNewCursorEnd());