diff options
Diffstat (limited to 'java/src/com/android/inputmethod')
6 files changed, 129 insertions, 73 deletions
diff --git a/java/src/com/android/inputmethod/latin/ByteArrayWrapper.java b/java/src/com/android/inputmethod/latin/ByteArrayWrapper.java new file mode 100644 index 000000000..15f70c50c --- /dev/null +++ b/java/src/com/android/inputmethod/latin/ByteArrayWrapper.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.latin; + +import com.android.inputmethod.latin.makedict.BinaryDictInputOutput.FusionDictionaryBufferInterface; + +/** + * This class provides an implementation for the FusionDictionary buffer interface that is backed + * by a simpled byte array. It allows to create a binary dictionary in memory. + */ +public final class ByteArrayWrapper implements FusionDictionaryBufferInterface { + private byte[] mBuffer; + private int mPosition; + + public ByteArrayWrapper(final byte[] buffer) { + mBuffer = buffer; + mPosition = 0; + } + + @Override + public int readUnsignedByte() { + return mBuffer[mPosition++] & 0xFF; + } + + @Override + public int readUnsignedShort() { + final int retval = readUnsignedByte(); + return (retval << 8) + readUnsignedByte(); + } + + @Override + public int readUnsignedInt24() { + final int retval = readUnsignedShort(); + return (retval << 8) + readUnsignedByte(); + } + + @Override + public int readInt() { + final int retval = readUnsignedShort(); + return (retval << 16) + readUnsignedShort(); + } + + @Override + public int position() { + return mPosition; + } + + @Override + public void position(int position) { + mPosition = position; + } + + @Override + public void put(final byte b) { + mBuffer[mPosition++] = b; + } + + @Override + public int limit() { + return mBuffer.length - 1; + } + + @Override + public int capacity() { + return mBuffer.length; + } +} diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 73ec57871..52a9b9a6c 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -201,6 +201,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 +242,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 +256,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 +273,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); @@ -474,8 +490,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. @@ -2619,18 +2644,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 diff --git a/java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java b/java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java index 10931555e..5233ed7d3 100644 --- a/java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java +++ b/java/src/com/android/inputmethod/latin/UserHistoryDictIOUtils.java @@ -53,64 +53,6 @@ public final class UserHistoryDictIOUtils { public int getFrequency(final String word1, final String word2); } - public static final class ByteArrayWrapper implements FusionDictionaryBufferInterface { - private byte[] mBuffer; - private int mPosition; - - public ByteArrayWrapper(final byte[] buffer) { - mBuffer = buffer; - mPosition = 0; - } - - @Override - public int readUnsignedByte() { - return mBuffer[mPosition++] & 0xFF; - } - - @Override - public int readUnsignedShort() { - final int retval = readUnsignedByte(); - return (retval << 8) + readUnsignedByte(); - } - - @Override - public int readUnsignedInt24() { - final int retval = readUnsignedShort(); - return (retval << 8) + readUnsignedByte(); - } - - @Override - public int readInt() { - final int retval = readUnsignedShort(); - return (retval << 16) + readUnsignedShort(); - } - - @Override - public int position() { - return mPosition; - } - - @Override - public void position(int position) { - mPosition = position; - } - - @Override - public void put(final byte b) { - mBuffer[mPosition++] = b; - } - - @Override - public int limit() { - return mBuffer.length - 1; - } - - @Override - public int capacity() { - return mBuffer.length; - } - } - /** * Writes dictionary to file. */ diff --git a/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java b/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java index 528028328..ab5724724 100644 --- a/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java +++ b/java/src/com/android/inputmethod/latin/UserHistoryDictionary.java @@ -261,7 +261,7 @@ public final class UserHistoryDictionary extends ExpandableDictionary { inStream = new FileInputStream(file); inStream.read(buffer); UserHistoryDictIOUtils.readDictionaryBinary( - new UserHistoryDictIOUtils.ByteArrayWrapper(buffer), listener); + new ByteArrayWrapper(buffer), listener); } catch (FileNotFoundException e) { // This is an expected condition: we don't have a user history dictionary for this // language yet. It will be created sometime later. diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java index f434a1211..916f483b9 100644 --- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java +++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripLayoutHelper.java @@ -449,8 +449,10 @@ final class SuggestionStripLayoutHelper { final TextView wordView = mWordViews.get(positionInStrip); wordView.setEnabled(true); wordView.setTextColor(mColorAutoCorrect); - final String punctuation = suggestedWords.getWord(positionInStrip); - wordView.setText(punctuation); + // {@link TextView#getTag()} is used to get the index in suggestedWords at + // {@link SuggestionStripView#onClick(View)}. + wordView.setTag(positionInStrip); + wordView.setText(suggestedWords.getWord(positionInStrip)); wordView.setTextScaleX(1.0f); wordView.setCompoundDrawables(null, null, null, null); stripView.addView(wordView); @@ -468,6 +470,8 @@ final class SuggestionStripLayoutHelper { final int wordWidth = (int)(width * mCenterSuggestionWeight); final CharSequence text = getEllipsizedText(word, wordWidth, wordView.getPaint()); final float wordScaleX = wordView.getTextScaleX(); + // {@link TextView#setTag()} is used to hold the word to be added to dictionary. The word + // will be extracted at {@link #getAddToDictionaryWord()}. wordView.setTag(word); wordView.setText(text); wordView.setTextScaleX(wordScaleX); @@ -497,8 +501,10 @@ final class SuggestionStripLayoutHelper { hintView.setOnClickListener(listener); } - public CharSequence getAddToDictionaryWord() { - return (CharSequence)mWordToSaveView.getTag(); + public String getAddToDictionaryWord() { + // String tag is set at + // {@link #layoutAddToDictionaryHint(String,ViewGroup,int,CharSequence,OnClickListener}. + return (String)mWordToSaveView.getTag(); } public boolean isAddToDictionaryShowing(final View v) { diff --git a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java index b2b9427af..2284a4607 100644 --- a/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java +++ b/java/src/com/android/inputmethod/latin/suggestions/SuggestionStripView.java @@ -306,12 +306,15 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick @Override public void onClick(final View view) { if (mLayoutHelper.isAddToDictionaryShowing(view)) { - mListener.addWordToUserDictionary(mLayoutHelper.getAddToDictionaryWord().toString()); + mListener.addWordToUserDictionary(mLayoutHelper.getAddToDictionaryWord()); clear(); return; } final Object tag = view.getTag(); + // Integer tag is set at + // {@link SuggestionStripLayoutHelper#setupWordViewsTextAndColor(SuggestedWords,int)} and + // {@link SuggestionStripLayoutHelper#layoutPunctuationSuggestions(SuggestedWords,ViewGroup} if (!(tag instanceof Integer)) { return; } |