Merge "Fix a bug where the cache would be out of sync"
commit
28e0b24965
|
@ -230,6 +230,9 @@ public final class RichInputConnection {
|
||||||
public void finishComposingText() {
|
public void finishComposingText() {
|
||||||
if (DEBUG_BATCH_NESTING) checkBatchEdit();
|
if (DEBUG_BATCH_NESTING) checkBatchEdit();
|
||||||
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
|
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
|
||||||
|
// TODO: this is not correct! The cursor is not necessarily after the composing text.
|
||||||
|
// In the practice right now this is only called when input ends so it will be reset so
|
||||||
|
// it works, but it's wrong and should be fixed.
|
||||||
mCommittedTextBeforeComposingText.append(mComposingText);
|
mCommittedTextBeforeComposingText.append(mComposingText);
|
||||||
mComposingText.setLength(0);
|
mComposingText.setLength(0);
|
||||||
if (null != mIC) {
|
if (null != mIC) {
|
||||||
|
@ -244,6 +247,9 @@ public final class RichInputConnection {
|
||||||
if (DEBUG_BATCH_NESTING) checkBatchEdit();
|
if (DEBUG_BATCH_NESTING) checkBatchEdit();
|
||||||
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
|
if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug();
|
||||||
mCommittedTextBeforeComposingText.append(text);
|
mCommittedTextBeforeComposingText.append(text);
|
||||||
|
// TODO: the following is exceedingly error-prone. Right now when the cursor is in the
|
||||||
|
// middle of the composing word mComposingText only holds the part of the composing text
|
||||||
|
// that is before the cursor, so this actually works, but it's terribly confusing. Fix this.
|
||||||
mExpectedSelStart += text.length() - mComposingText.length();
|
mExpectedSelStart += text.length() - mComposingText.length();
|
||||||
mExpectedSelEnd = mExpectedSelStart;
|
mExpectedSelEnd = mExpectedSelStart;
|
||||||
mComposingText.setLength(0);
|
mComposingText.setLength(0);
|
||||||
|
@ -347,6 +353,9 @@ public final class RichInputConnection {
|
||||||
|
|
||||||
public void deleteSurroundingText(final int beforeLength, final int afterLength) {
|
public void deleteSurroundingText(final int beforeLength, final int afterLength) {
|
||||||
if (DEBUG_BATCH_NESTING) checkBatchEdit();
|
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
|
||||||
|
// come here in this case, but we need to fix this.
|
||||||
final int remainingChars = mComposingText.length() - beforeLength;
|
final int remainingChars = mComposingText.length() - beforeLength;
|
||||||
if (remainingChars >= 0) {
|
if (remainingChars >= 0) {
|
||||||
mComposingText.setLength(remainingChars);
|
mComposingText.setLength(remainingChars);
|
||||||
|
@ -447,8 +456,12 @@ public final class RichInputConnection {
|
||||||
getTextBeforeCursor(Constants.EDITOR_CONTENTS_CACHE_SIZE + (end - start), 0);
|
getTextBeforeCursor(Constants.EDITOR_CONTENTS_CACHE_SIZE + (end - start), 0);
|
||||||
mCommittedTextBeforeComposingText.setLength(0);
|
mCommittedTextBeforeComposingText.setLength(0);
|
||||||
if (!TextUtils.isEmpty(textBeforeCursor)) {
|
if (!TextUtils.isEmpty(textBeforeCursor)) {
|
||||||
|
// The cursor is not necessarily at the end of the composing text, but we have its
|
||||||
|
// position in mExpectedSelStart and mExpectedSelEnd. In this case we want the start
|
||||||
|
// of the text, so we should use mExpectedSelStart. In other words, the composing
|
||||||
|
// text starts (mExpectedSelStart - start) characters before the end of textBeforeCursor
|
||||||
final int indexOfStartOfComposingText =
|
final int indexOfStartOfComposingText =
|
||||||
Math.max(textBeforeCursor.length() - (end - start), 0);
|
Math.max(textBeforeCursor.length() - (mExpectedSelStart - start), 0);
|
||||||
mComposingText.append(textBeforeCursor.subSequence(indexOfStartOfComposingText,
|
mComposingText.append(textBeforeCursor.subSequence(indexOfStartOfComposingText,
|
||||||
textBeforeCursor.length()));
|
textBeforeCursor.length()));
|
||||||
mCommittedTextBeforeComposingText.append(
|
mCommittedTextBeforeComposingText.append(
|
||||||
|
@ -544,6 +557,9 @@ public final class RichInputConnection {
|
||||||
final int checkLength = LOOKBACK_CHARACTER_NUM - 1;
|
final int checkLength = LOOKBACK_CHARACTER_NUM - 1;
|
||||||
final String reference = prev.length() <= checkLength ? prev.toString()
|
final String reference = prev.length() <= checkLength ? prev.toString()
|
||||||
: prev.subSequence(prev.length() - checkLength, prev.length()).toString();
|
: prev.subSequence(prev.length() - checkLength, prev.length()).toString();
|
||||||
|
// TODO: right now the following works because mComposingText holds the part of the
|
||||||
|
// composing text that is before the cursor, but this is very confusing. We should
|
||||||
|
// fix it.
|
||||||
final StringBuilder internal = new StringBuilder()
|
final StringBuilder internal = new StringBuilder()
|
||||||
.append(mCommittedTextBeforeComposingText).append(mComposingText);
|
.append(mCommittedTextBeforeComposingText).append(mComposingText);
|
||||||
if (internal.length() > checkLength) {
|
if (internal.length() > checkLength) {
|
||||||
|
|
|
@ -385,4 +385,41 @@ public class InputLogicTests extends InputTestsBase {
|
||||||
final SuggestedWords suggestedWords = mLatinIME.getSuggestedWordsForTest();
|
final SuggestedWords suggestedWords = mLatinIME.getSuggestedWordsForTest();
|
||||||
assertEquals("no prediction after period", 0, suggestedWords.size());
|
assertEquals("no prediction after period", 0, suggestedWords.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testPredictionsAfterRecorrection() {
|
||||||
|
final String PREFIX = "A ";
|
||||||
|
final String WORD_TO_TYPE = "Barack";
|
||||||
|
final String FIRST_NON_TYPED_SUGGESTION = "Barrack";
|
||||||
|
final int endOfPrefix = PREFIX.length();
|
||||||
|
final int endOfWord = endOfPrefix + WORD_TO_TYPE.length();
|
||||||
|
final int endOfSuggestion = endOfPrefix + FIRST_NON_TYPED_SUGGESTION.length();
|
||||||
|
final int indexForManualCursor = endOfPrefix + 3; // +3 because it's after "Bar" in "Barack"
|
||||||
|
type(PREFIX);
|
||||||
|
mLatinIME.onUpdateSelection(0, 0, endOfPrefix, endOfPrefix, -1, -1);
|
||||||
|
type(WORD_TO_TYPE);
|
||||||
|
pickSuggestionManually(1, FIRST_NON_TYPED_SUGGESTION);
|
||||||
|
mLatinIME.onUpdateSelection(endOfPrefix, endOfPrefix, endOfSuggestion, endOfSuggestion,
|
||||||
|
-1, -1);
|
||||||
|
runMessages();
|
||||||
|
type(" ");
|
||||||
|
mLatinIME.onUpdateSelection(endOfSuggestion, endOfSuggestion,
|
||||||
|
endOfSuggestion + 1, endOfSuggestion + 1, -1, -1);
|
||||||
|
sleep(DELAY_TO_WAIT_FOR_PREDICTIONS);
|
||||||
|
runMessages();
|
||||||
|
// Simulate a manual cursor move
|
||||||
|
mInputConnection.setSelection(indexForManualCursor, indexForManualCursor);
|
||||||
|
mLatinIME.onUpdateSelection(endOfSuggestion + 1, endOfSuggestion + 1,
|
||||||
|
indexForManualCursor, indexForManualCursor, -1, -1);
|
||||||
|
sleep(DELAY_TO_WAIT_FOR_PREDICTIONS);
|
||||||
|
runMessages();
|
||||||
|
pickSuggestionManually(0, WORD_TO_TYPE);
|
||||||
|
mLatinIME.onUpdateSelection(indexForManualCursor, indexForManualCursor,
|
||||||
|
endOfWord, endOfWord, -1, -1);
|
||||||
|
sleep(DELAY_TO_WAIT_FOR_PREDICTIONS);
|
||||||
|
runMessages();
|
||||||
|
// Test the first prediction is displayed
|
||||||
|
final SuggestedWords suggestedWords = mLatinIME.getSuggestedWords();
|
||||||
|
assertEquals("predictions after recorrection", "Obama",
|
||||||
|
suggestedWords.size() > 0 ? suggestedWords.getWord(0) : null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue