Cleanup before fixing getTextAfterCursor().

We never delete text after the cursor, so constrain the API accordingly.
Define the number of characters to read before and after.
Set them to reasonable values.
The next CL will start caching text after the cursor.

Bug 21926256.

Change-Id: Idd58daf68614de4a69344aa3c8a4323720c5d3a0
main
Dan Zivkovic 2015-06-19 12:06:18 -07:00
parent 02c28453fc
commit 0232e73dfa
2 changed files with 22 additions and 27 deletions

View File

@ -16,8 +16,6 @@
package com.android.inputmethod.latin;
import static com.android.inputmethod.latin.define.DecoderSpecificConstants.DICTIONARY_MAX_WORD_LENGTH;
import android.inputmethodservice.InputMethodService;
import android.os.Build;
import android.os.Bundle;
@ -37,7 +35,6 @@ import com.android.inputmethod.compat.InputConnectionCompatUtils;
import com.android.inputmethod.latin.common.Constants;
import com.android.inputmethod.latin.common.UnicodeSurrogate;
import com.android.inputmethod.latin.common.StringUtils;
import com.android.inputmethod.latin.define.DecoderSpecificConstants;
import com.android.inputmethod.latin.inputlogic.PrivateCommandPerformer;
import com.android.inputmethod.latin.settings.SpacingAndPunctuations;
import com.android.inputmethod.latin.utils.CapsModeUtils;
@ -59,14 +56,12 @@ import javax.annotation.Nullable;
* for example.
*/
public final class RichInputConnection implements PrivateCommandPerformer {
private static final String TAG = RichInputConnection.class.getSimpleName();
private static final String TAG = "RichInputConnection";
private static final boolean DBG = false;
private static final boolean DEBUG_PREVIOUS_TEXT = false;
private static final boolean DEBUG_BATCH_NESTING = false;
// Provision for realistic N-grams like "Hello, how are you?" and "I'm running 5 late".
// Technically, this will not handle 5-grams composed of long words, but in practice,
// our language models don't include that much data.
private static final int LOOKBACK_CHARACTER_NUM = 80;
private static final int NUM_CHARS_TO_GET_BEFORE_CURSOR = 40;
private static final int NUM_CHARS_TO_GET_AFTER_CURSOR = 40;
private static final int INVALID_CURSOR_POSITION = -1;
/**
@ -85,7 +80,7 @@ public final class RichInputConnection implements PrivateCommandPerformer {
private int mExpectedSelEnd = INVALID_CURSOR_POSITION; // in chars, not code points
/**
* This contains the committed text immediately preceding the cursor and the composing
* text if any. It is refreshed when the cursor moves by calling upon the TextView.
* text, if any. It is refreshed when the cursor moves by calling upon the TextView.
*/
private final StringBuilder mCommittedTextBeforeComposingText = new StringBuilder();
/**
@ -386,7 +381,7 @@ public final class RichInputConnection implements PrivateCommandPerformer {
return isConnected() ? mIC.getTextAfterCursor(n, flags) : null;
}
public void deleteSurroundingText(final int beforeLength, final int afterLength) {
public void deleteTextBeforeCursor(final int beforeLength) {
if (DEBUG_BATCH_NESTING) checkBatchEdit();
// TODO: the following is incorrect if the cursor is not immediately after the composition.
// Right now we never come here in this case because we reset the composing state before we
@ -411,7 +406,7 @@ public final class RichInputConnection implements PrivateCommandPerformer {
mExpectedSelStart = 0;
}
if (isConnected()) {
mIC.deleteSurroundingText(beforeLength, afterLength);
mIC.deleteSurroundingText(beforeLength, 0);
}
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
}
@ -576,9 +571,9 @@ public final class RichInputConnection implements PrivateCommandPerformer {
if (!isConnected()) {
return NgramContext.EMPTY_PREV_WORDS_INFO;
}
final CharSequence prev = getTextBeforeCursor(LOOKBACK_CHARACTER_NUM, 0);
final CharSequence prev = getTextBeforeCursor(NUM_CHARS_TO_GET_BEFORE_CURSOR, 0);
if (DEBUG_PREVIOUS_TEXT && null != prev) {
final int checkLength = LOOKBACK_CHARACTER_NUM - 1;
final int checkLength = NUM_CHARS_TO_GET_BEFORE_CURSOR - 1;
final String reference = prev.length() <= checkLength ? prev.toString()
: prev.subSequence(prev.length() - checkLength, prev.length()).toString();
// TODO: right now the following works because mComposingText holds the part of the
@ -621,9 +616,9 @@ public final class RichInputConnection implements PrivateCommandPerformer {
if (!isConnected()) {
return null;
}
final CharSequence before = mIC.getTextBeforeCursor(LOOKBACK_CHARACTER_NUM,
final CharSequence before = mIC.getTextBeforeCursor(NUM_CHARS_TO_GET_BEFORE_CURSOR,
InputConnection.GET_TEXT_WITH_STYLES);
final CharSequence after = mIC.getTextAfterCursor(LOOKBACK_CHARACTER_NUM,
final CharSequence after = mIC.getTextAfterCursor(NUM_CHARS_TO_GET_AFTER_CURSOR,
InputConnection.GET_TEXT_WITH_STYLES);
if (before == null || after == null) {
return null;
@ -704,7 +699,7 @@ public final class RichInputConnection implements PrivateCommandPerformer {
if (DEBUG_BATCH_NESTING) checkBatchEdit();
final int codePointBeforeCursor = getCodePointBeforeCursor();
if (Constants.CODE_SPACE == codePointBeforeCursor) {
deleteSurroundingText(1, 0);
deleteTextBeforeCursor(1);
}
}
@ -730,7 +725,7 @@ public final class RichInputConnection implements PrivateCommandPerformer {
}
// Double-space results in ". ". A backspace to cancel this should result in a single
// space in the text field, so we replace ". " with a single space.
deleteSurroundingText(2, 0);
deleteTextBeforeCursor(2);
final String singleSpace = " ";
commitText(singleSpace, 1);
return true;
@ -752,7 +747,7 @@ public final class RichInputConnection implements PrivateCommandPerformer {
+ "find a space just before the cursor.");
return false;
}
deleteSurroundingText(2, 0);
deleteTextBeforeCursor(2);
final String text = " " + textBeforeCursor.subSequence(0, 1);
commitText(text, 1);
return true;

View File

@ -1053,7 +1053,7 @@ public final class InputLogic {
// Cancel multi-character input: remove the text we just entered.
// This is triggered on backspace after a key that inputs multiple characters,
// like the smiley key or the .com key.
mConnection.deleteSurroundingText(mEnteredText.length(), 0);
mConnection.deleteTextBeforeCursor(mEnteredText.length());
StatsUtils.onDeleteMultiCharInput(mEnteredText.length());
mEnteredText = null;
// If we have mEnteredText, then we know that mHasUncommittedTypedChars == false.
@ -1098,7 +1098,7 @@ public final class InputLogic {
- mConnection.getExpectedSelectionStart();
mConnection.setSelection(mConnection.getExpectedSelectionEnd(),
mConnection.getExpectedSelectionEnd());
mConnection.deleteSurroundingText(numCharsDeleted, 0);
mConnection.deleteTextBeforeCursor(numCharsDeleted);
StatsUtils.onBackspaceSelectedText(numCharsDeleted);
} else {
// There is no selection, just delete one character.
@ -1138,13 +1138,13 @@ public final class InputLogic {
// broken apps expect something to happen in this case so that they can
// catch it and have their broken interface react. If you need the keyboard
// to do this, you're doing it wrong -- please fix your app.
mConnection.deleteSurroundingText(1, 0);
mConnection.deleteTextBeforeCursor(1);
// TODO: Add a new StatsUtils method onBackspaceWhenNoText()
return;
}
final int lengthToDelete =
Character.isSupplementaryCodePoint(codePointBeforeCursor) ? 2 : 1;
mConnection.deleteSurroundingText(lengthToDelete, 0);
mConnection.deleteTextBeforeCursor(lengthToDelete);
int totalDeletedLength = lengthToDelete;
if (mDeleteCount > Constants.DELETE_ACCELERATE_AT) {
// If this is an accelerated (i.e., double) deletion, then we need to
@ -1157,7 +1157,7 @@ public final class InputLogic {
if (codePointBeforeCursorToDeleteAgain != Constants.NOT_A_CODE) {
final int lengthToDeleteAgain = Character.isSupplementaryCodePoint(
codePointBeforeCursorToDeleteAgain) ? 2 : 1;
mConnection.deleteSurroundingText(lengthToDeleteAgain, 0);
mConnection.deleteTextBeforeCursor(lengthToDeleteAgain);
totalDeletedLength += lengthToDeleteAgain;
}
}
@ -1241,7 +1241,7 @@ public final class InputLogic {
if (Constants.CODE_SPACE != codePointBeforeCursor) {
return false;
}
mConnection.deleteSurroundingText(1, 0);
mConnection.deleteTextBeforeCursor(1);
final String text = event.getTextToCommit() + " ";
mConnection.commitText(text, 1);
inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW);
@ -1331,7 +1331,7 @@ public final class InputLogic {
Character.codePointAt(lastTwo, length - 3) : lastTwo.charAt(length - 2);
if (canBeFollowedByDoubleSpacePeriod(firstCodePoint)) {
cancelDoubleSpacePeriodCountdown();
mConnection.deleteSurroundingText(1, 0);
mConnection.deleteTextBeforeCursor(1);
final String textToInsert = inputTransaction.mSettingsValues.mSpacingAndPunctuations
.mSentenceSeparatorAndSpace;
mConnection.commitText(textToInsert, 1);
@ -1399,7 +1399,7 @@ public final class InputLogic {
mConnection.finishComposingText();
mRecapitalizeStatus.rotate();
mConnection.setSelection(selectionEnd, selectionEnd);
mConnection.deleteSurroundingText(numCharsSelected, 0);
mConnection.deleteTextBeforeCursor(numCharsSelected);
mConnection.commitText(mRecapitalizeStatus.getRecapitalizedString(), 0);
mConnection.setSelection(mRecapitalizeStatus.getNewCursorStart(),
mRecapitalizeStatus.getNewCursorEnd());
@ -1637,7 +1637,7 @@ public final class InputLogic {
+ "\", but before the cursor we found \"" + wordBeforeCursor + "\"");
}
}
mConnection.deleteSurroundingText(deleteLength, 0);
mConnection.deleteTextBeforeCursor(deleteLength);
if (!TextUtils.isEmpty(committedWord)) {
unlearnWord(committedWordString, inputTransaction.mSettingsValues,
Constants.EVENT_REVERT);