aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
diff options
context:
space:
mode:
authorTom Ouyang <ouyang@google.com>2015-06-22 13:43:32 -0700
committerTom Ouyang <ouyang@google.com>2015-06-23 10:34:44 -0700
commit912016b69f1c0e26ec58ee9d17c8ac7e5711d70d (patch)
tree08ea2fedab96e7958edef6115c5d5d266f716779 /java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
parent73aaf6833780c1915dd4ab7d3f0f55e3af130f99 (diff)
downloadlatinime-912016b69f1c0e26ec58ee9d17c8ac7e5711d70d.tar.gz
latinime-912016b69f1c0e26ec58ee9d17c8ac7e5711d70d.tar.xz
latinime-912016b69f1c0e26ec58ee9d17c8ac7e5711d70d.zip
Workaround for preserving responsiveness on a slow InputConnection.
1. Add mechanism to detect a slow or non-resonsive InputConnection (IC) 2. When IC slowness is detected, skip certain IC calls that are known to be expensive (e.g., getTextAfterCursor). 3. Similarly, disables learning / unlearning on a slow IC. 4. IC slowness flag is reset when starting input on a new TextView or when a fixed amount of time has passed. Note: These are mostly temporary workarounds. The permanent solution is to refactor RichInputConnection so that it is less sensitive to IC slowness in general. Bug: 21926256 Change-Id: I383fab0516d3f3a8e0f71e5d760a8336a7730f7c
Diffstat (limited to 'java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java')
-rw-r--r--java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java33
1 files changed, 28 insertions, 5 deletions
diff --git a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
index 87c3ddbc8..03c4ec62f 100644
--- a/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
+++ b/java/src/com/android/inputmethod/latin/inputlogic/InputLogic.java
@@ -139,6 +139,7 @@ public final class InputLogic {
public void startInput(final String combiningSpec, final SettingsValues settingsValues) {
mEnteredText = null;
mWordBeingCorrectedByCursor = null;
+ mConnection.onStartInput();
if (!mWordComposer.getTypedWord().isEmpty()) {
// For messaging apps that offer send button, the IME does not get the opportunity
// to capture the last word. This block should capture those uncommitted words.
@@ -472,7 +473,7 @@ public final class InputLogic {
}
// Try to record the word being corrected when the user enters a word character or
// the backspace key.
- if (!mWordComposer.isComposingWord()
+ if (!mConnection.hasSlowInputConnection() && !mWordComposer.isComposingWord()
&& (settingsValues.isWordCodePoint(processedEvent.mCodePoint) ||
processedEvent.mKeyCode == Constants.CODE_DELETE)) {
mWordBeingCorrectedByCursor = getWordAtCursor(
@@ -832,8 +833,14 @@ public final class InputLogic {
&& settingsValues.needsToLookupSuggestions() &&
// In languages with spaces, we only start composing a word when we are not already
// touching a word. In languages without spaces, the above conditions are sufficient.
- (!mConnection.isCursorTouchingWord(settingsValues.mSpacingAndPunctuations)
- || !settingsValues.mSpacingAndPunctuations.mCurrentLanguageHasSpaces)) {
+ // NOTE: If the InputConnection is slow, we skip the text-after-cursor check since it
+ // can incur a very expensive getTextAfterCursor() lookup, potentially making the
+ // keyboard UI slow and non-responsive.
+ // TODO: Cache the text after the cursor so we don't need to go to the InputConnection
+ // each time. We are already doing this for getTextBeforeCursor().
+ (!settingsValues.mSpacingAndPunctuations.mCurrentLanguageHasSpaces
+ || !mConnection.isCursorTouchingWord(settingsValues.mSpacingAndPunctuations,
+ !mConnection.hasSlowInputConnection() /* checkTextAfter */))) {
// Reset entirely the composing state anyway, then start composing a new word unless
// the character is a word connector. The idea here is, word connectors are not
// separators and they should be treated as normal characters, except in the first
@@ -1169,7 +1176,9 @@ public final class InputLogic {
unlearnWordBeingDeleted(
inputTransaction.mSettingsValues, currentKeyboardScriptId);
}
- if (inputTransaction.mSettingsValues.isSuggestionsEnabledPerUserSettings()
+ if (mConnection.hasSlowInputConnection()) {
+ mSuggestionStripViewAccessor.setNeutralSuggestionStrip();
+ } else if (inputTransaction.mSettingsValues.isSuggestionsEnabledPerUserSettings()
&& inputTransaction.mSettingsValues.mSpacingAndPunctuations
.mCurrentLanguageHasSpaces
&& !mConnection.isCursorFollowedByWordCharacter(
@@ -1196,6 +1205,13 @@ public final class InputLogic {
boolean unlearnWordBeingDeleted(
final SettingsValues settingsValues, final int currentKeyboardScriptId) {
+ if (mConnection.hasSlowInputConnection()) {
+ // TODO: Refactor unlearning so that it does not incur any extra calls
+ // to the InputConnection. That way it can still be performed on a slow
+ // InputConnection.
+ Log.w(TAG, "Skipping unlearning due to slow InputConnection.");
+ return false;
+ }
// If we just started backspacing to delete a previous word (but have not
// entered the composing state yet), unlearn the word.
// TODO: Consider tracking whether or not this word was typed by the user.
@@ -1411,6 +1427,12 @@ public final class InputLogic {
// That's to avoid unintended additions in some sensitive fields, or fields that
// expect to receive non-words.
if (!settingsValues.mAutoCorrectionEnabledPerUserSettings) return;
+ if (mConnection.hasSlowInputConnection()) {
+ // Since we don't unlearn when the user backspaces on a slow InputConnection,
+ // turn off learning to guard against adding typos that the user later deletes.
+ Log.w(TAG, "Skipping learning due to slow InputConnection.");
+ return;
+ }
if (TextUtils.isEmpty(suggestion)) return;
final boolean wasAutoCapitalized =
@@ -1514,7 +1536,8 @@ public final class InputLogic {
return;
}
final int expectedCursorPosition = mConnection.getExpectedSelectionStart();
- if (!mConnection.isCursorTouchingWord(settingsValues.mSpacingAndPunctuations)) {
+ if (!mConnection.isCursorTouchingWord(settingsValues.mSpacingAndPunctuations,
+ true /* checkTextAfter */)) {
// Show predictions.
mWordComposer.setCapitalizedModeAtStartComposingTime(WordComposer.CAPS_MODE_OFF);
mLatinIME.mHandler.postUpdateSuggestionStrip(SuggestedWords.INPUT_STYLE_RECORRECTION);