Fix SubtypeSwitcher initialization path

This change also removes the reference of LatinIME from
SubtypeSwitcher.

Bug: 7026856
Change-Id: I78a266f3682b11f09b49bbcdcdb6aee713e6af37
main
Tadashi G. Takaoka 2012-08-22 10:19:56 +09:00
parent 1f05cf6dab
commit 9fc6af325e
3 changed files with 76 additions and 52 deletions

View File

@ -405,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);
@ -529,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;
@ -596,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) {
@ -664,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.
@ -1285,7 +1298,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()));
@ -1689,7 +1702,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();
}
@ -2057,9 +2071,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();

View File

@ -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() {

View File

@ -135,7 +135,6 @@ public class InputTestsBase extends ServiceTestCase<LatinIME> {
mLatinIME.onCreateInputView();
mLatinIME.onStartInputView(ei, false);
mInputConnection = ic;
mKeyboard = mLatinIME.mKeyboardSwitcher.getKeyboard();
changeLanguage("en_US");
}
@ -253,6 +252,8 @@ public class InputTestsBase extends ServiceTestCase<LatinIME> {
fail("InputMethodSubtype for locale " + locale + " is not enabled");
}
SubtypeSwitcher.getInstance().updateSubtype(subtype);
mLatinIME.loadKeyboard();
mKeyboard = mLatinIME.mKeyboardSwitcher.getKeyboard();
waitForDictionaryToBeLoaded();
}