diff options
Diffstat (limited to 'java/src/com/android/inputmethod/latin/LatinIME.java')
-rw-r--r-- | java/src/com/android/inputmethod/latin/LatinIME.java | 82 |
1 files changed, 63 insertions, 19 deletions
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 73ec57871..0efe0eba7 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -43,7 +43,7 @@ import android.os.Message; import android.os.SystemClock; import android.preference.PreferenceManager; import android.text.InputType; -import android.text.SpannableString; +import android.text.Spanned; import android.text.TextUtils; import android.text.style.SuggestionSpan; import android.util.Log; @@ -76,9 +76,20 @@ import com.android.inputmethod.keyboard.KeyboardSwitcher; import com.android.inputmethod.keyboard.MainKeyboardView; import com.android.inputmethod.latin.RichInputConnection.Range; import com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; -import com.android.inputmethod.latin.Utils.Stats; import com.android.inputmethod.latin.define.ProductionFlag; import com.android.inputmethod.latin.suggestions.SuggestionStripView; +import com.android.inputmethod.latin.utils.CapsModeUtils; +import com.android.inputmethod.latin.utils.CollectionUtils; +import com.android.inputmethod.latin.utils.CompletionInfoUtils; +import com.android.inputmethod.latin.utils.InputTypeUtils; +import com.android.inputmethod.latin.utils.IntentUtils; +import com.android.inputmethod.latin.utils.JniUtils; +import com.android.inputmethod.latin.utils.PositionalInfoForUserDictPendingAddition; +import com.android.inputmethod.latin.utils.RecapitalizeStatus; +import com.android.inputmethod.latin.utils.StaticInnerHandlerWrapper; +import com.android.inputmethod.latin.utils.TargetPackageInfoGetterTask; +import com.android.inputmethod.latin.utils.Utils; +import com.android.inputmethod.latin.utils.Utils.Stats; import com.android.inputmethod.research.ResearchLogger; import java.io.FileDescriptor; @@ -201,6 +212,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen private static final int MSG_UPDATE_SUGGESTION_STRIP = 2; private static final int MSG_SHOW_GESTURE_PREVIEW_AND_SUGGESTION_STRIP = 3; private static final int MSG_RESUME_SUGGESTIONS = 4; + private static final int MSG_REOPEN_DICTIONARIES = 5; private static final int ARG1_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT = 1; @@ -241,6 +253,13 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen case MSG_RESUME_SUGGESTIONS: latinIme.restartSuggestionsOnWordTouchedByCursor(); break; + case MSG_REOPEN_DICTIONARIES: + latinIme.initSuggest(); + // In theory we could call latinIme.updateSuggestionStrip() right away, but + // in the practice, the dictionary is not finished opening yet so we wouldn't + // get any suggestions. Wait one frame. + postUpdateSuggestionStrip(); + break; } } @@ -248,6 +267,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen sendMessageDelayed(obtainMessage(MSG_UPDATE_SUGGESTION_STRIP), mDelayUpdateSuggestions); } + public void postReopenDictionaries() { + sendMessage(obtainMessage(MSG_REOPEN_DICTIONARIES)); + } + public void postResumeSuggestions() { removeMessages(MSG_RESUME_SUGGESTIONS); sendMessageDelayed(obtainMessage(MSG_RESUME_SUGGESTIONS), mDelayUpdateSuggestions); @@ -261,6 +284,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen return hasMessages(MSG_UPDATE_SUGGESTION_STRIP); } + public boolean hasPendingReopenDictionaries() { + return hasMessages(MSG_REOPEN_DICTIONARIES); + } + public void postUpdateShiftState() { removeMessages(MSG_UPDATE_SHIFT_STATE); sendMessageDelayed(obtainMessage(MSG_UPDATE_SHIFT_STATE), mDelayUpdateShiftState); @@ -413,6 +440,12 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } } + // Loading the native library eagerly to avoid unexpected UnsatisfiedLinkError at the initial + // JNI call as much as possible. + static { + JniUtils.loadNativeLibrary(); + } + public LatinIME() { super(); mSettings = Settings.getInstance(); @@ -474,8 +507,17 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen new InputAttributes(getCurrentInputEditorInfo(), isFullscreenMode()); mSettings.loadSettings(locale, inputAttributes); AudioAndHapticFeedbackManager.getInstance().onSettingsChanged(mSettings.getCurrent()); - // May need to reset the contacts dictionary depending on the user settings. - resetContactsDictionary(null == mSuggest ? null : mSuggest.getContactsDictionary()); + // To load the keyboard we need to load all the settings once, but resetting the + // contacts dictionary should be deferred until after the new layout has been displayed + // to improve responsivity. In the language switching process, we post a reopenDictionaries + // message, then come here to read the settings for the new language before we change + // the layout; at this time, we need to skip resetting the contacts dictionary. It will + // be done later inside {@see #initSuggest()} when the reopenDictionaries message is + // processed. + if (!mHandler.hasPendingReopenDictionaries()) { + // May need to reset the contacts dictionary depending on the user settings. + resetContactsDictionary(null == mSuggest ? null : mSuggest.getContactsDictionary()); + } } // Note that this method is called from a non-UI thread. @@ -2470,13 +2512,15 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen if (null == range) return; // Happens if we don't have an input connection at all // If for some strange reason (editor bug or so) we measure the text before the cursor as // longer than what the entire text is supposed to be, the safe thing to do is bail out. - if (range.mCharsBefore > mLastSelectionStart) return; + final int numberOfCharsInWordBeforeCursor = range.getNumberOfCharsInWordBeforeCursor(); + if (numberOfCharsInWordBeforeCursor > mLastSelectionStart) return; final ArrayList<SuggestedWordInfo> suggestions = CollectionUtils.newArrayList(); - final String typedWord = range.mWord.toString(); - if (range.mWord instanceof SpannableString) { - final SpannableString spannableString = (SpannableString)range.mWord; + final CharSequence word = range.mWord; + final String typedWord = word.toString(); + if (word instanceof Spanned) { + final Spanned spanned = (Spanned)word; int i = 0; - for (Object object : spannableString.getSpans(0, spannableString.length(), + for (Object object : spanned.getSpans(0, spanned.length(), SuggestionSpan.class)) { SuggestionSpan span = (SuggestionSpan)object; for (String s : span.getSuggestions()) { @@ -2490,9 +2534,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } } mWordComposer.setComposingWord(typedWord, mKeyboardSwitcher.getKeyboard()); - mWordComposer.setCursorPositionWithinWord(range.mCharsBefore); - mConnection.setComposingRegion(mLastSelectionStart - range.mCharsBefore, - mLastSelectionEnd + range.mCharsAfter); + mWordComposer.setCursorPositionWithinWord(numberOfCharsInWordBeforeCursor); + mConnection.setComposingRegion( + mLastSelectionStart - numberOfCharsInWordBeforeCursor, + mLastSelectionEnd + range.getNumberOfCharsInWordAfterCursor()); final SuggestedWords suggestedWords; if (suggestions.isEmpty()) { // We come here if there weren't any suggestion spans on this word. We will try to @@ -2619,18 +2664,17 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // Outside LatinIME, only used by the {@link InputTestsBase} test suite. @UsedForTesting void loadKeyboard() { - // TODO: Why are we calling {@link #loadSettings()} and {@link #initSuggest()} in a - // different order than in {@link #onStartInputView}? - initSuggest(); + // Since we are switching languages, the most urgent thing is to let the keyboard graphics + // update. LoadKeyboard does that, but we need to wait for buffer flip for it to be on + // the screen. Anything we do right now will delay this, so wait until the next frame + // before we do the rest, like reopening dictionaries and updating suggestions. So we + // post a message. + mHandler.postReopenDictionaries(); loadSettings(); if (mKeyboardSwitcher.getMainKeyboardView() != null) { // Reload keyboard because the current language has been changed. mKeyboardSwitcher.loadKeyboard(getCurrentInputEditorInfo(), mSettings.getCurrent()); } - // Since we just changed languages, we should re-evaluate suggestions with whatever word - // we are currently composing. If we are not composing anything, we may want to display - // predictions or punctuation signs (which is done by the updateSuggestionStrip anyway). - mHandler.postUpdateSuggestionStrip(); } // Callback called by PointerTracker through the KeyboardActionListener. This is called when a |