diff --git a/java/src/com/android/inputmethod/latin/RichInputConnection.java b/java/src/com/android/inputmethod/latin/RichInputConnection.java index b3cddba23..80e137a34 100644 --- a/java/src/com/android/inputmethod/latin/RichInputConnection.java +++ b/java/src/com/android/inputmethod/latin/RichInputConnection.java @@ -64,7 +64,7 @@ public final class RichInputConnection { * It's not really the cursor position: the cursor may not be there yet, and it's also expected * there be cases where it never actually comes to be there. */ - private int mExpectedCursorPosition = INVALID_CURSOR_POSITION; // in chars, not code points + private int mExpectedSelStart = 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. @@ -103,16 +103,16 @@ public final class RichInputConnection { final String reference = (beforeCursor.length() <= actualLength) ? beforeCursor.toString() : beforeCursor.subSequence(beforeCursor.length() - actualLength, beforeCursor.length()).toString(); - if (et.selectionStart != mExpectedCursorPosition + if (et.selectionStart != mExpectedSelStart || !(reference.equals(internal.toString()))) { - final String context = "Expected cursor position = " + mExpectedCursorPosition - + "\nActual cursor position = " + et.selectionStart + final String context = "Expected selection start = " + mExpectedSelStart + + "\nActual selection start = " + et.selectionStart + "\nExpected text = " + internal.length() + " " + internal + "\nActual text = " + reference.length() + " " + reference; ((LatinIME)mParent).debugDumpStateAndCrashWithException(context); } else { Log.e(TAG, DebugLogUtils.getStackTrace(2)); - Log.e(TAG, "Exp <> Actual : " + mExpectedCursorPosition + " <> " + et.selectionStart); + Log.e(TAG, "Exp <> Actual : " + mExpectedSelStart + " <> " + et.selectionStart); } } @@ -150,15 +150,15 @@ public final class RichInputConnection { * data, so we empty the cache and note that we don't know the new cursor position, and we * return false so that the caller knows about this and can retry later. * - * @param newCursorPosition The new position of the cursor, as received from the system. + * @param newSelStart The new position of the selection start, as received from the system. * @param shouldFinishComposition Whether we should finish the composition in progress. * @return true if we were able to connect to the editor successfully, false otherwise. When * this method returns false, the caches could not be correctly refreshed so they were only * reset: the caller should try again later to return to normal operation. */ - public boolean resetCachesUponCursorMoveAndReturnSuccess(final int newCursorPosition, + public boolean resetCachesUponCursorMoveAndReturnSuccess(final int newSelStart, final boolean shouldFinishComposition) { - mExpectedCursorPosition = newCursorPosition; + mExpectedSelStart = newSelStart; mComposingText.setLength(0); final boolean didReloadTextSuccessfully = reloadTextCache(); if (!didReloadTextSuccessfully) { @@ -166,14 +166,14 @@ public final class RichInputConnection { return false; } final int lengthOfTextBeforeCursor = mCommittedTextBeforeComposingText.length(); - if (lengthOfTextBeforeCursor > newCursorPosition + if (lengthOfTextBeforeCursor > newSelStart || (lengthOfTextBeforeCursor < Constants.EDITOR_CONTENTS_CACHE_SIZE - && newCursorPosition < Constants.EDITOR_CONTENTS_CACHE_SIZE)) { - // newCursorPosition may be lying -- when rotating the device (probably a framework - // bug). If we have less chars than we asked for, then we know how many chars we have, - // and if we got more than newCursorPosition says, then we know it was lying. In both - // cases the length is more reliable - mExpectedCursorPosition = lengthOfTextBeforeCursor; + && newSelStart < Constants.EDITOR_CONTENTS_CACHE_SIZE)) { + // newSelStart may be lying -- when rotating the device (probably a framework bug). If + // we have less chars than we asked for, then we know how many chars we have, and if we + // got more than newSelStart says, then we know it was lying. In both cases the length + // is more reliable. + mExpectedSelStart = lengthOfTextBeforeCursor; } if (null != mIC && shouldFinishComposition) { mIC.finishComposingText(); @@ -199,7 +199,7 @@ public final class RichInputConnection { if (null == textBeforeCursor) { // For some reason the app thinks we are not connected to it. This looks like a // framework bug... Fall back to ground state and return false. - mExpectedCursorPosition = INVALID_CURSOR_POSITION; + mExpectedSelStart = INVALID_CURSOR_POSITION; Log.e(TAG, "Unable to connect to the editor to retrieve text."); return false; } @@ -232,7 +232,7 @@ public final class RichInputConnection { if (DEBUG_BATCH_NESTING) checkBatchEdit(); if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug(); mCommittedTextBeforeComposingText.append(text); - mExpectedCursorPosition += text.length() - mComposingText.length(); + mExpectedSelStart += text.length() - mComposingText.length(); mComposingText.setLength(0); if (null != mIC) { mIC.commitText(text, i); @@ -245,7 +245,7 @@ public final class RichInputConnection { } public boolean canDeleteCharacters() { - return mExpectedCursorPosition > 0; + return mExpectedSelStart > 0; } /** @@ -282,7 +282,7 @@ public final class RichInputConnection { // heavy pressing of delete, for example DEFAULT_TEXT_CACHE_SIZE - 5 times or so. // getCapsMode should be updated to be able to return a "not enough info" result so that // we can get more context only when needed. - if (TextUtils.isEmpty(mCommittedTextBeforeComposingText) && 0 != mExpectedCursorPosition) { + if (TextUtils.isEmpty(mCommittedTextBeforeComposingText) && 0 != mExpectedSelStart) { if (!reloadTextCache()) { Log.w(TAG, "Unable to connect to the editor. " + "Setting caps mode without knowing text."); @@ -308,8 +308,8 @@ public final class RichInputConnection { // However, if we don't have an expected cursor position, then we should always // go fetch the cache again (as it happens, INVALID_CURSOR_POSITION < 0, so we need to // test for this explicitly) - if (INVALID_CURSOR_POSITION != mExpectedCursorPosition - && (cachedLength >= n || cachedLength >= mExpectedCursorPosition)) { + if (INVALID_CURSOR_POSITION != mExpectedSelStart + && (cachedLength >= n || cachedLength >= mExpectedSelStart)) { final StringBuilder s = new StringBuilder(mCommittedTextBeforeComposingText); // We call #toString() here to create a temporary object. // In some situations, this method is called on a worker thread, and it's possible @@ -349,10 +349,10 @@ public final class RichInputConnection { + remainingChars, 0); mCommittedTextBeforeComposingText.setLength(len); } - if (mExpectedCursorPosition > beforeLength) { - mExpectedCursorPosition -= beforeLength; + if (mExpectedSelStart > beforeLength) { + mExpectedSelStart -= beforeLength; } else { - mExpectedCursorPosition = 0; + mExpectedSelStart = 0; } if (null != mIC) { mIC.deleteSurroundingText(beforeLength, afterLength); @@ -386,7 +386,7 @@ public final class RichInputConnection { switch (keyEvent.getKeyCode()) { case KeyEvent.KEYCODE_ENTER: mCommittedTextBeforeComposingText.append("\n"); - mExpectedCursorPosition += 1; + mExpectedSelStart += 1; break; case KeyEvent.KEYCODE_DEL: if (0 == mComposingText.length()) { @@ -398,18 +398,18 @@ public final class RichInputConnection { } else { mComposingText.delete(mComposingText.length() - 1, mComposingText.length()); } - if (mExpectedCursorPosition > 0) mExpectedCursorPosition -= 1; + if (mExpectedSelStart > 0) mExpectedSelStart -= 1; break; case KeyEvent.KEYCODE_UNKNOWN: if (null != keyEvent.getCharacters()) { mCommittedTextBeforeComposingText.append(keyEvent.getCharacters()); - mExpectedCursorPosition += keyEvent.getCharacters().length(); + mExpectedSelStart += keyEvent.getCharacters().length(); } break; default: final String text = new String(new int[] { keyEvent.getUnicodeChar() }, 0, 1); mCommittedTextBeforeComposingText.append(text); - mExpectedCursorPosition += text.length(); + mExpectedSelStart += text.length(); break; } } @@ -443,7 +443,7 @@ public final class RichInputConnection { public void setComposingText(final CharSequence text, final int newCursorPosition) { if (DEBUG_BATCH_NESTING) checkBatchEdit(); if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug(); - mExpectedCursorPosition += text.length() - mComposingText.length(); + mExpectedSelStart += text.length() - mComposingText.length(); mComposingText.setLength(0); mComposingText.append(text); // TODO: support values of i != 1. At this time, this is never called with i != 1. @@ -469,7 +469,7 @@ public final class RichInputConnection { public boolean setSelection(final int start, final int end) { if (DEBUG_BATCH_NESTING) checkBatchEdit(); if (DEBUG_PREVIOUS_TEXT) checkConsistencyForDebug(); - mExpectedCursorPosition = start; + mExpectedSelStart = start; if (null != mIC) { final boolean isIcValid = mIC.setSelection(start, end); if (!isIcValid) { @@ -500,7 +500,7 @@ public final class RichInputConnection { // text should never be null, but just in case, it's better to insert nothing than to crash if (null == text) text = ""; mCommittedTextBeforeComposingText.append(text); - mExpectedCursorPosition += text.length() - mComposingText.length(); + mExpectedSelStart += text.length() - mComposingText.length(); mComposingText.setLength(0); if (null != mIC) { mIC.commitCompletion(completionInfo); @@ -788,14 +788,14 @@ public final class RichInputConnection { */ public boolean isBelatedExpectedUpdate(final int oldSelStart, final int newSelStart) { // If this is an update that arrives at our expected position, it's a belated update. - if (newSelStart == mExpectedCursorPosition) return true; + if (newSelStart == mExpectedSelStart) return true; // If this is an update that moves the cursor from our expected position, it must be // an explicit move. - if (oldSelStart == mExpectedCursorPosition) return false; + if (oldSelStart == mExpectedSelStart) return false; // The following returns true if newSelStart is between oldSelStart and // mCurrentCursorPosition. We assume that if the updated position is between the old // position and the expected position, then it must be a belated update. - return (newSelStart - oldSelStart) * (mExpectedCursorPosition - newSelStart) >= 0; + return (newSelStart - oldSelStart) * (mExpectedSelStart - newSelStart) >= 0; } /**