diff options
Diffstat (limited to 'java/src/com/android/inputmethod/latin')
5 files changed, 82 insertions, 102 deletions
diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java index c04a99b6a..8909526d8 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java @@ -63,7 +63,7 @@ public class BinaryDictionary extends Dictionary { private final boolean mUseFullEditDistance; private final SparseArray<DicTraverseSession> mDicTraverseSessions = - new SparseArray<DicTraverseSession>(); + CollectionUtils.newSparseArray(); // TODO: There should be a way to remove used DicTraverseSession objects from // {@code mDicTraverseSessions}. diff --git a/java/src/com/android/inputmethod/latin/CollectionUtils.java b/java/src/com/android/inputmethod/latin/CollectionUtils.java index 789b79a0a..baa2ee1cd 100644 --- a/java/src/com/android/inputmethod/latin/CollectionUtils.java +++ b/java/src/com/android/inputmethod/latin/CollectionUtils.java @@ -16,6 +16,8 @@ package com.android.inputmethod.latin; +import android.util.SparseArray; + import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -86,4 +88,8 @@ public class CollectionUtils { public static <E> CopyOnWriteArrayList<E> newCopyOnWriteArrayList(final E[] array) { return new CopyOnWriteArrayList<E>(array); } + + public static <E> SparseArray<E> newSparseArray() { + return new SparseArray<E>(); + } } diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 0729d0f7d..df200cd0e 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -381,18 +381,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen ImfUtils.setAdditionalInputMethodSubtypes(this, mCurrentSettings.getAdditionalSubtypes()); - Utils.GCUtils.getInstance().reset(); - boolean tryGC = true; - // Shouldn't this be removed? I think that from Honeycomb on, the GC is now actually working - // as expected and this code is useless. - for (int i = 0; i < Utils.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) { - try { - initSuggest(); - tryGC = false; - } catch (OutOfMemoryError e) { - tryGC = Utils.GCUtils.getInstance().tryGCOrWait("InitSuggest", e); - } - } + initSuggest(); mDisplayOrientation = res.getConfiguration().orientation; @@ -416,7 +405,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen } // Has to be package-visible for unit tests - /* package */ void loadSettings() { + /* package for test */ + void loadSettings() { // Note that the calling sequence of onCreate() and onCurrentInputMethodSubtypeChanged() // is not guaranteed. It may even be called at the same time on a different thread. if (null == mPrefs) mPrefs = PreferenceManager.getDefaultSharedPreferences(this); @@ -540,7 +530,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen @Override public void onConfigurationChanged(Configuration conf) { - mSubtypeSwitcher.onConfigurationChanged(conf); + // System locale has been changed. Needs to reload keyboard. + if (mSubtypeSwitcher.onConfigurationChanged(conf, this)) { + loadKeyboard(); + } // If orientation changed while predicting, commit the change if (mDisplayOrientation != conf.orientation) { mDisplayOrientation = conf.orientation; @@ -607,6 +600,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // Note that the calling sequence of onCreate() and onCurrentInputMethodSubtypeChanged() // is not guaranteed. It may even be called at the same time on a different thread. mSubtypeSwitcher.updateSubtype(subtype); + loadKeyboard(); } private void onStartInputInternal(EditorInfo editorInfo, boolean restarting) { @@ -675,7 +669,15 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen final boolean inputTypeChanged = !mCurrentSettings.isSameInputType(editorInfo); final boolean isDifferentTextField = !restarting || inputTypeChanged; if (isDifferentTextField) { - mSubtypeSwitcher.updateParametersOnStartInputView(); + final boolean currentSubtypeEnabled = mSubtypeSwitcher + .updateParametersOnStartInputViewAndReturnIfCurrentSubtypeEnabled(); + if (!currentSubtypeEnabled) { + // Current subtype is disabled. Needs to update subtype and keyboard. + final InputMethodSubtype newSubtype = ImfUtils.getCurrentInputMethodSubtype( + this, mSubtypeSwitcher.getNoLanguageSubtype()); + mSubtypeSwitcher.updateSubtype(newSubtype); + loadKeyboard(); + } } // The EditorInfo might have a flag that affects fullscreen mode. @@ -1291,7 +1293,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen onSettingsKeyPressed(); break; case Keyboard.CODE_SHORTCUT: - mSubtypeSwitcher.switchToShortcutIME(); + mSubtypeSwitcher.switchToShortcutIME(this); break; case Keyboard.CODE_ACTION_ENTER: performEditorAction(getActionId(switcher.getKeyboard())); @@ -1698,7 +1700,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen // TODO: make this private // Outside LatinIME, only used by the test suite. - /* package for tests */ boolean isShowingPunctuationList() { + /* package for tests */ + boolean isShowingPunctuationList() { if (mSuggestionStripView == null) return false; return mCurrentSettings.mSuggestPuncList == mSuggestionStripView.getSuggestions(); } @@ -2066,9 +2069,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen return mCurrentSettings.isWordSeparator(code); } - // Notify that language or mode have been changed and toggleLanguage will update KeyboardID - // according to new language or mode. Called from SubtypeSwitcher. - public void onRefreshKeyboard() { + // TODO: Make this private + // Outside LatinIME, only used by the {@link InputTestsBase} test suite. + /* package for test */ + void loadKeyboard() { // When the device locale is changed in SetupWizard etc., this method may get called via // onConfigurationChanged before SoftInputWindow is shown. initSuggest(); diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java index a7a5fcb5f..c693edcca 100644 --- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java +++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java @@ -22,6 +22,7 @@ import android.content.Context; import android.content.Intent; import android.content.res.Configuration; import android.content.res.Resources; +import android.inputmethodservice.InputMethodService; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.AsyncTask; @@ -42,7 +43,6 @@ public class SubtypeSwitcher { private static final String TAG = SubtypeSwitcher.class.getSimpleName(); private static final SubtypeSwitcher sInstance = new SubtypeSwitcher(); - private /* final */ LatinIME mService; private /* final */ InputMethodManager mImm; private /* final */ Resources mResources; private /* final */ ConnectivityManager mConnectivityManager; @@ -68,11 +68,11 @@ public class SubtypeSwitcher { return mEnabledSubtypeCount >= 2 || !mIsSystemLanguageSameAsInputLanguage; } - public void updateEnabledSubtypeCount(int count) { + public void updateEnabledSubtypeCount(final int count) { mEnabledSubtypeCount = count; } - public void updateIsSystemLanguageSameAsInputLanguage(boolean isSame) { + public void updateIsSystemLanguageSameAsInputLanguage(final boolean isSame) { mIsSystemLanguageSameAsInputLanguage = isSame; } } @@ -81,18 +81,17 @@ public class SubtypeSwitcher { return sInstance; } - public static void init(LatinIME service) { - SubtypeLocale.init(service); - sInstance.initialize(service); - sInstance.updateAllParameters(); + public static void init(final Context context) { + SubtypeLocale.init(context); + sInstance.initialize(context); + sInstance.updateAllParameters(context); } private SubtypeSwitcher() { // Intentional empty constructor for singleton. } - private void initialize(LatinIME service) { - mService = service; + private void initialize(final Context service) { mResources = service.getResources(); mImm = ImfUtils.getInputMethodManager(service); mConnectivityManager = (ConnectivityManager) service.getSystemService( @@ -111,39 +110,46 @@ public class SubtypeSwitcher { // Update all parameters stored in SubtypeSwitcher. // Only configuration changed event is allowed to call this because this is heavy. - private void updateAllParameters() { + private void updateAllParameters(final Context context) { mCurrentSystemLocale = mResources.getConfiguration().locale; - updateSubtype(ImfUtils.getCurrentInputMethodSubtype(mService, mNoLanguageSubtype)); - updateParametersOnStartInputView(); + updateSubtype(ImfUtils.getCurrentInputMethodSubtype(context, mNoLanguageSubtype)); + updateParametersOnStartInputViewAndReturnIfCurrentSubtypeEnabled(); } - // Update parameters which are changed outside LatinIME. This parameters affect UI so they - // should be updated every time onStartInputview. - public void updateParametersOnStartInputView() { - updateEnabledSubtypes(); + /** + * Update parameters which are changed outside LatinIME. This parameters affect UI so they + * should be updated every time onStartInputView. + * + * @return true if the current subtype is enabled. + */ + public boolean updateParametersOnStartInputViewAndReturnIfCurrentSubtypeEnabled() { + final boolean currentSubtypeEnabled = + updateEnabledSubtypesAndReturnIfEnabled(mCurrentSubtype); updateShortcutIME(); + return currentSubtypeEnabled; } - // Reload enabledSubtypes from the framework. - private void updateEnabledSubtypes() { - final InputMethodSubtype currentSubtype = mCurrentSubtype; - boolean foundCurrentSubtypeBecameDisabled = true; + /** + * Update enabled subtypes from the framework. + * + * @param subtype the subtype to be checked + * @return true if the {@code subtype} is enabled. + */ + private boolean updateEnabledSubtypesAndReturnIfEnabled(final InputMethodSubtype subtype) { final List<InputMethodSubtype> enabledSubtypesOfThisIme = mImm.getEnabledInputMethodSubtypeList(null, true); - for (InputMethodSubtype ims : enabledSubtypesOfThisIme) { - if (ims.equals(currentSubtype)) { - foundCurrentSubtypeBecameDisabled = false; - } - } mNeedsToDisplayLanguage.updateEnabledSubtypeCount(enabledSubtypesOfThisIme.size()); - if (foundCurrentSubtypeBecameDisabled) { - if (DBG) { - Log.w(TAG, "Last subtype: " - + currentSubtype.getLocale() + "/" + currentSubtype.getExtraValue()); - Log.w(TAG, "Last subtype was disabled. Update to the current one."); + + for (final InputMethodSubtype ims : enabledSubtypesOfThisIme) { + if (ims.equals(subtype)) { + return true; } - updateSubtype(ImfUtils.getCurrentInputMethodSubtype(mService, mNoLanguageSubtype)); } + if (DBG) { + Log.w(TAG, "Subtype: " + subtype.getLocale() + "/" + subtype.getExtraValue() + + " was disabled"); + } + return false; } private void updateShortcutIME() { @@ -159,8 +165,8 @@ public class SubtypeSwitcher { mImm.getShortcutInputMethodsAndSubtypes(); mShortcutInputMethodInfo = null; mShortcutSubtype = null; - for (InputMethodInfo imi : shortcuts.keySet()) { - List<InputMethodSubtype> subtypes = shortcuts.get(imi); + for (final InputMethodInfo imi : shortcuts.keySet()) { + final List<InputMethodSubtype> subtypes = shortcuts.get(imi); // TODO: Returns the first found IMI for now. Should handle all shortcuts as // appropriate. mShortcutInputMethodInfo = imi; @@ -194,24 +200,24 @@ public class SubtypeSwitcher { mCurrentSubtype = newSubtype; updateShortcutIME(); - mService.onRefreshKeyboard(); } //////////////////////////// // Shortcut IME functions // //////////////////////////// - public void switchToShortcutIME() { + public void switchToShortcutIME(final InputMethodService context) { if (mShortcutInputMethodInfo == null) { return; } final String imiId = mShortcutInputMethodInfo.getId(); - switchToTargetIME(imiId, mShortcutSubtype); + switchToTargetIME(imiId, mShortcutSubtype, context); } - private void switchToTargetIME(final String imiId, final InputMethodSubtype subtype) { - final IBinder token = mService.getWindow().getWindow().getAttributes().token; + private void switchToTargetIME(final String imiId, final InputMethodSubtype subtype, + final InputMethodService context) { + final IBinder token = context.getWindow().getWindow().getAttributes().token; if (token == null) { return; } @@ -253,7 +259,7 @@ public class SubtypeSwitcher { return true; } - public void onNetworkStateChanged(Intent intent) { + public void onNetworkStateChanged(final Intent intent) { final boolean noConnection = intent.getBooleanExtra( ConnectivityManager.EXTRA_NO_CONNECTIVITY, false); mIsNetworkConnected = !noConnection; @@ -265,7 +271,7 @@ public class SubtypeSwitcher { // Subtype Switching functions // ////////////////////////////////// - public boolean needsToDisplayLanguage(Locale keyboardLocale) { + public boolean needsToDisplayLanguage(final Locale keyboardLocale) { if (keyboardLocale.toString().equals(SubtypeLocale.NO_LANGUAGE)) { return true; } @@ -279,12 +285,14 @@ public class SubtypeSwitcher { return SubtypeLocale.getSubtypeLocale(mCurrentSubtype); } - public void onConfigurationChanged(Configuration conf) { + public boolean onConfigurationChanged(final Configuration conf, final Context context) { final Locale systemLocale = conf.locale; + final boolean systemLocaleChanged = !systemLocale.equals(mCurrentSystemLocale); // If system configuration was changed, update all parameters. - if (!systemLocale.equals(mCurrentSystemLocale)) { - updateAllParameters(); + if (systemLocaleChanged) { + updateAllParameters(context); } + return systemLocaleChanged; } public InputMethodSubtype getCurrentSubtype() { diff --git a/java/src/com/android/inputmethod/latin/Utils.java b/java/src/com/android/inputmethod/latin/Utils.java index 9997569a2..fc7a42100 100644 --- a/java/src/com/android/inputmethod/latin/Utils.java +++ b/java/src/com/android/inputmethod/latin/Utils.java @@ -65,44 +65,6 @@ public class Utils { } } - public static class GCUtils { - private static final String GC_TAG = GCUtils.class.getSimpleName(); - public static final int GC_TRY_COUNT = 2; - // GC_TRY_LOOP_MAX is used for the hard limit of GC wait, - // GC_TRY_LOOP_MAX should be greater than GC_TRY_COUNT. - public static final int GC_TRY_LOOP_MAX = 5; - private static final long GC_INTERVAL = DateUtils.SECOND_IN_MILLIS; - private static GCUtils sInstance = new GCUtils(); - private int mGCTryCount = 0; - - public static GCUtils getInstance() { - return sInstance; - } - - public void reset() { - mGCTryCount = 0; - } - - public boolean tryGCOrWait(String metaData, Throwable t) { - if (mGCTryCount == 0) { - System.gc(); - } - if (++mGCTryCount > GC_TRY_COUNT) { - LatinImeLogger.logOnException(metaData, t); - return false; - } else { - try { - Thread.sleep(GC_INTERVAL); - return true; - } catch (InterruptedException e) { - Log.e(GC_TAG, "Sleep was interrupted."); - LatinImeLogger.logOnException(metaData, t); - return false; - } - } - } - } - /* package */ static class RingCharBuffer { private static RingCharBuffer sRingCharBuffer = new RingCharBuffer(); private static final char PLACEHOLDER_DELIMITER_CHAR = '\uFFFC'; |