diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 8f918040f..a2ecc107f 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -219,8 +219,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen latinIme.onEndBatchInputAsyncInternal((SuggestedWords) msg.obj); break; case MSG_RESET_CACHES: - latinIme.retryResetCaches(msg.arg1 == 1 /* tryResumeSuggestions */, - msg.arg2 /* remainingTries */); + latinIme.mInputLogic.retryResetCaches(latinIme.mSettings.getCurrent(), + msg.arg1 == 1 /* tryResumeSuggestions */, + msg.arg2 /* remainingTries */, + latinIme.mKeyboardSwitcher, this); break; } } @@ -812,7 +814,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen mInputLogic.mLastSelectionEnd = editorInfo.initialSelEnd; // In some cases (namely, after rotation of the device) editorInfo.initialSelStart is lying // so we try using some heuristics to find out about these and fix them. - tryFixLyingCursorPosition(); + mInputLogic.tryFixLyingCursorPosition(); mHandler.cancelUpdateSuggestionStrip(); mHandler.cancelDoubleSpacePeriodTimer(); @@ -831,44 +833,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen if (TRACE) Debug.startMethodTracing("/data/trace/latinime"); } - /** - * Try to get the text from the editor to expose lies the framework may have been - * telling us. Concretely, when the device rotates, the frameworks tells us about where the - * cursor used to be initially in the editor at the time it first received the focus; this - * may be completely different from the place it is upon rotation. Since we don't have any - * means to get the real value, try at least to ask the text view for some characters and - * detect the most damaging cases: when the cursor position is declared to be much smaller - * than it really is. - */ - private void tryFixLyingCursorPosition() { - final CharSequence textBeforeCursor = mInputLogic.mConnection.getTextBeforeCursor( - Constants.EDITOR_CONTENTS_CACHE_SIZE, 0); - if (null == textBeforeCursor) { - mInputLogic.mLastSelectionStart = mInputLogic.mLastSelectionEnd = - Constants.NOT_A_CURSOR_POSITION; - } else { - final int textLength = textBeforeCursor.length(); - if (textLength > mInputLogic.mLastSelectionStart - || (textLength < Constants.EDITOR_CONTENTS_CACHE_SIZE - && mInputLogic.mLastSelectionStart < - Constants.EDITOR_CONTENTS_CACHE_SIZE)) { - // It should not be possible to have only one of those variables be - // NOT_A_CURSOR_POSITION, so if they are equal, either the selection is zero-sized - // (simple cursor, no selection) or there is no cursor/we don't know its pos - final boolean wasEqual = - mInputLogic.mLastSelectionStart == mInputLogic.mLastSelectionEnd; - mInputLogic.mLastSelectionStart = textLength; - // We can't figure out the value of mLastSelectionEnd :( - // But at least if it's smaller than mLastSelectionStart something is wrong, - // and if they used to be equal we also don't want to make it look like there is a - // selection. - if (wasEqual || mInputLogic.mLastSelectionStart > mInputLogic.mLastSelectionEnd) { - mInputLogic.mLastSelectionEnd = mInputLogic.mLastSelectionStart; - } - } - } - } - @Override public void onWindowHidden() { super.onWindowHidden(); @@ -1894,31 +1858,6 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen mHandler.showSuggestionStripWithTypedWord(suggestedWords, typedWord); } - /** - * Retry resetting caches in the rich input connection. - * - * When the editor can't be accessed we can't reset the caches, so we schedule a retry. - * This method handles the retry, and re-schedules a new retry if we still can't access. - * We only retry up to 5 times before giving up. - * - * @param tryResumeSuggestions Whether we should resume suggestions or not. - * @param remainingTries How many times we may try again before giving up. - */ - private void retryResetCaches(final boolean tryResumeSuggestions, final int remainingTries) { - if (!mInputLogic.mConnection.resetCachesUponCursorMoveAndReturnSuccess( - mInputLogic.mLastSelectionStart, mInputLogic.mLastSelectionEnd, false)) { - if (0 < remainingTries) { - mHandler.postResetCaches(tryResumeSuggestions, remainingTries - 1); - return; - } - // If remainingTries is 0, we should stop waiting for new tries, but it's still - // better to load the keyboard (less things will be broken). - } - tryFixLyingCursorPosition(); - mKeyboardSwitcher.loadKeyboard(getCurrentInputEditorInfo(), mSettings.getCurrent()); - if (tryResumeSuggestions) mHandler.postResumeSuggestions(); - } - // TODO: Make this private // Outside LatinIME, only used by the {@link InputTestsBase} test suite. @UsedForTesting diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java index 5f3297794..8f7bb95fb 100644 --- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java +++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java @@ -1528,4 +1528,72 @@ public final class InputLogic { mWordComposer.discardPreviousWordForSuggestion(); } } + + /** + * Try to get the text from the editor to expose lies the framework may have been + * telling us. Concretely, when the device rotates, the frameworks tells us about where the + * cursor used to be initially in the editor at the time it first received the focus; this + * may be completely different from the place it is upon rotation. Since we don't have any + * means to get the real value, try at least to ask the text view for some characters and + * detect the most damaging cases: when the cursor position is declared to be much smaller + * than it really is. + */ + // TODO: make this private + public void tryFixLyingCursorPosition() { + final CharSequence textBeforeCursor = mConnection.getTextBeforeCursor( + Constants.EDITOR_CONTENTS_CACHE_SIZE, 0); + if (null == textBeforeCursor) { + mLastSelectionStart = mLastSelectionEnd = Constants.NOT_A_CURSOR_POSITION; + } else { + final int textLength = textBeforeCursor.length(); + if (textLength > mLastSelectionStart + || (textLength < Constants.EDITOR_CONTENTS_CACHE_SIZE + && mLastSelectionStart < Constants.EDITOR_CONTENTS_CACHE_SIZE)) { + // It should not be possible to have only one of those variables be + // NOT_A_CURSOR_POSITION, so if they are equal, either the selection is zero-sized + // (simple cursor, no selection) or there is no cursor/we don't know its pos + final boolean wasEqual = mLastSelectionStart == mLastSelectionEnd; + mLastSelectionStart = textLength; + // We can't figure out the value of mLastSelectionEnd :( + // But at least if it's smaller than mLastSelectionStart something is wrong, + // and if they used to be equal we also don't want to make it look like there is a + // selection. + if (wasEqual || mLastSelectionStart > mLastSelectionEnd) { + mLastSelectionEnd = mLastSelectionStart; + } + } + } + } + + /** + * Retry resetting caches in the rich input connection. + * + * When the editor can't be accessed we can't reset the caches, so we schedule a retry. + * This method handles the retry, and re-schedules a new retry if we still can't access. + * We only retry up to 5 times before giving up. + * + * @param settingsValues the current values of the settings. + * @param tryResumeSuggestions Whether we should resume suggestions or not. + * @param remainingTries How many times we may try again before giving up. + */ + // TODO: make this private + public void retryResetCaches(final SettingsValues settingsValues, + final boolean tryResumeSuggestions, final int remainingTries, + // TODO: remove these arguments + final KeyboardSwitcher keyboardSwitcher, final LatinIME.UIHandler handler) { + if (!mConnection.resetCachesUponCursorMoveAndReturnSuccess( + mLastSelectionStart, mLastSelectionEnd, false)) { + if (0 < remainingTries) { + handler.postResetCaches(tryResumeSuggestions, remainingTries - 1); + return; + } + // If remainingTries is 0, we should stop waiting for new tries, but it's still + // better to load the keyboard (less things will be broken). + } + tryFixLyingCursorPosition(); + keyboardSwitcher.loadKeyboard(getCurrentInputEditorInfo(), settingsValues); + if (tryResumeSuggestions) { + handler.postResumeSuggestions(); + } + } }