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 // 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() // 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. // is not guaranteed. It may even be called at the same time on a different thread.
if (null == mPrefs) mPrefs = PreferenceManager.getDefaultSharedPreferences(this); if (null == mPrefs) mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
@ -529,7 +530,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
@Override @Override
public void onConfigurationChanged(Configuration conf) { 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 orientation changed while predicting, commit the change
if (mDisplayOrientation != conf.orientation) { if (mDisplayOrientation != conf.orientation) {
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() // 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. // is not guaranteed. It may even be called at the same time on a different thread.
mSubtypeSwitcher.updateSubtype(subtype); mSubtypeSwitcher.updateSubtype(subtype);
loadKeyboard();
} }
private void onStartInputInternal(EditorInfo editorInfo, boolean restarting) { 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 inputTypeChanged = !mCurrentSettings.isSameInputType(editorInfo);
final boolean isDifferentTextField = !restarting || inputTypeChanged; final boolean isDifferentTextField = !restarting || inputTypeChanged;
if (isDifferentTextField) { 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. // The EditorInfo might have a flag that affects fullscreen mode.
@ -1285,7 +1298,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
onSettingsKeyPressed(); onSettingsKeyPressed();
break; break;
case Keyboard.CODE_SHORTCUT: case Keyboard.CODE_SHORTCUT:
mSubtypeSwitcher.switchToShortcutIME(); mSubtypeSwitcher.switchToShortcutIME(this);
break; break;
case Keyboard.CODE_ACTION_ENTER: case Keyboard.CODE_ACTION_ENTER:
performEditorAction(getActionId(switcher.getKeyboard())); performEditorAction(getActionId(switcher.getKeyboard()));
@ -1689,7 +1702,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// TODO: make this private // TODO: make this private
// Outside LatinIME, only used by the test suite. // Outside LatinIME, only used by the test suite.
/* package for tests */ boolean isShowingPunctuationList() { /* package for tests */
boolean isShowingPunctuationList() {
if (mSuggestionStripView == null) return false; if (mSuggestionStripView == null) return false;
return mCurrentSettings.mSuggestPuncList == mSuggestionStripView.getSuggestions(); return mCurrentSettings.mSuggestPuncList == mSuggestionStripView.getSuggestions();
} }
@ -2057,9 +2071,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
return mCurrentSettings.isWordSeparator(code); return mCurrentSettings.isWordSeparator(code);
} }
// Notify that language or mode have been changed and toggleLanguage will update KeyboardID // TODO: Make this private
// according to new language or mode. Called from SubtypeSwitcher. // Outside LatinIME, only used by the {@link InputTestsBase} test suite.
public void onRefreshKeyboard() { /* package for test */
void loadKeyboard() {
// When the device locale is changed in SetupWizard etc., this method may get called via // When the device locale is changed in SetupWizard etc., this method may get called via
// onConfigurationChanged before SoftInputWindow is shown. // onConfigurationChanged before SoftInputWindow is shown.
initSuggest(); initSuggest();

View File

@ -22,6 +22,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.inputmethodservice.InputMethodService;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.net.NetworkInfo; import android.net.NetworkInfo;
import android.os.AsyncTask; import android.os.AsyncTask;
@ -42,7 +43,6 @@ public class SubtypeSwitcher {
private static final String TAG = SubtypeSwitcher.class.getSimpleName(); private static final String TAG = SubtypeSwitcher.class.getSimpleName();
private static final SubtypeSwitcher sInstance = new SubtypeSwitcher(); private static final SubtypeSwitcher sInstance = new SubtypeSwitcher();
private /* final */ LatinIME mService;
private /* final */ InputMethodManager mImm; private /* final */ InputMethodManager mImm;
private /* final */ Resources mResources; private /* final */ Resources mResources;
private /* final */ ConnectivityManager mConnectivityManager; private /* final */ ConnectivityManager mConnectivityManager;
@ -68,11 +68,11 @@ public class SubtypeSwitcher {
return mEnabledSubtypeCount >= 2 || !mIsSystemLanguageSameAsInputLanguage; return mEnabledSubtypeCount >= 2 || !mIsSystemLanguageSameAsInputLanguage;
} }
public void updateEnabledSubtypeCount(int count) { public void updateEnabledSubtypeCount(final int count) {
mEnabledSubtypeCount = count; mEnabledSubtypeCount = count;
} }
public void updateIsSystemLanguageSameAsInputLanguage(boolean isSame) { public void updateIsSystemLanguageSameAsInputLanguage(final boolean isSame) {
mIsSystemLanguageSameAsInputLanguage = isSame; mIsSystemLanguageSameAsInputLanguage = isSame;
} }
} }
@ -81,18 +81,17 @@ public class SubtypeSwitcher {
return sInstance; return sInstance;
} }
public static void init(LatinIME service) { public static void init(final Context context) {
SubtypeLocale.init(service); SubtypeLocale.init(context);
sInstance.initialize(service); sInstance.initialize(context);
sInstance.updateAllParameters(); sInstance.updateAllParameters(context);
} }
private SubtypeSwitcher() { private SubtypeSwitcher() {
// Intentional empty constructor for singleton. // Intentional empty constructor for singleton.
} }
private void initialize(LatinIME service) { private void initialize(final Context service) {
mService = service;
mResources = service.getResources(); mResources = service.getResources();
mImm = ImfUtils.getInputMethodManager(service); mImm = ImfUtils.getInputMethodManager(service);
mConnectivityManager = (ConnectivityManager) service.getSystemService( mConnectivityManager = (ConnectivityManager) service.getSystemService(
@ -111,39 +110,46 @@ public class SubtypeSwitcher {
// Update all parameters stored in SubtypeSwitcher. // Update all parameters stored in SubtypeSwitcher.
// Only configuration changed event is allowed to call this because this is heavy. // 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; mCurrentSystemLocale = mResources.getConfiguration().locale;
updateSubtype(ImfUtils.getCurrentInputMethodSubtype(mService, mNoLanguageSubtype)); updateSubtype(ImfUtils.getCurrentInputMethodSubtype(context, mNoLanguageSubtype));
updateParametersOnStartInputView(); updateParametersOnStartInputViewAndReturnIfCurrentSubtypeEnabled();
} }
// Update parameters which are changed outside LatinIME. This parameters affect UI so they /**
// should be updated every time onStartInputview. * Update parameters which are changed outside LatinIME. This parameters affect UI so they
public void updateParametersOnStartInputView() { * should be updated every time onStartInputView.
updateEnabledSubtypes(); *
* @return true if the current subtype is enabled.
*/
public boolean updateParametersOnStartInputViewAndReturnIfCurrentSubtypeEnabled() {
final boolean currentSubtypeEnabled =
updateEnabledSubtypesAndReturnIfEnabled(mCurrentSubtype);
updateShortcutIME(); updateShortcutIME();
return currentSubtypeEnabled;
} }
// Reload enabledSubtypes from the framework. /**
private void updateEnabledSubtypes() { * Update enabled subtypes from the framework.
final InputMethodSubtype currentSubtype = mCurrentSubtype; *
boolean foundCurrentSubtypeBecameDisabled = true; * @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 = final List<InputMethodSubtype> enabledSubtypesOfThisIme =
mImm.getEnabledInputMethodSubtypeList(null, true); mImm.getEnabledInputMethodSubtypeList(null, true);
for (InputMethodSubtype ims : enabledSubtypesOfThisIme) {
if (ims.equals(currentSubtype)) {
foundCurrentSubtypeBecameDisabled = false;
}
}
mNeedsToDisplayLanguage.updateEnabledSubtypeCount(enabledSubtypesOfThisIme.size()); mNeedsToDisplayLanguage.updateEnabledSubtypeCount(enabledSubtypesOfThisIme.size());
if (foundCurrentSubtypeBecameDisabled) {
if (DBG) { for (final InputMethodSubtype ims : enabledSubtypesOfThisIme) {
Log.w(TAG, "Last subtype: " if (ims.equals(subtype)) {
+ currentSubtype.getLocale() + "/" + currentSubtype.getExtraValue()); return true;
Log.w(TAG, "Last subtype was disabled. Update to the current one.");
} }
updateSubtype(ImfUtils.getCurrentInputMethodSubtype(mService, mNoLanguageSubtype));
} }
if (DBG) {
Log.w(TAG, "Subtype: " + subtype.getLocale() + "/" + subtype.getExtraValue()
+ " was disabled");
}
return false;
} }
private void updateShortcutIME() { private void updateShortcutIME() {
@ -159,8 +165,8 @@ public class SubtypeSwitcher {
mImm.getShortcutInputMethodsAndSubtypes(); mImm.getShortcutInputMethodsAndSubtypes();
mShortcutInputMethodInfo = null; mShortcutInputMethodInfo = null;
mShortcutSubtype = null; mShortcutSubtype = null;
for (InputMethodInfo imi : shortcuts.keySet()) { for (final InputMethodInfo imi : shortcuts.keySet()) {
List<InputMethodSubtype> subtypes = shortcuts.get(imi); final List<InputMethodSubtype> subtypes = shortcuts.get(imi);
// TODO: Returns the first found IMI for now. Should handle all shortcuts as // TODO: Returns the first found IMI for now. Should handle all shortcuts as
// appropriate. // appropriate.
mShortcutInputMethodInfo = imi; mShortcutInputMethodInfo = imi;
@ -194,24 +200,24 @@ public class SubtypeSwitcher {
mCurrentSubtype = newSubtype; mCurrentSubtype = newSubtype;
updateShortcutIME(); updateShortcutIME();
mService.onRefreshKeyboard();
} }
//////////////////////////// ////////////////////////////
// Shortcut IME functions // // Shortcut IME functions //
//////////////////////////// ////////////////////////////
public void switchToShortcutIME() { public void switchToShortcutIME(final InputMethodService context) {
if (mShortcutInputMethodInfo == null) { if (mShortcutInputMethodInfo == null) {
return; return;
} }
final String imiId = mShortcutInputMethodInfo.getId(); final String imiId = mShortcutInputMethodInfo.getId();
switchToTargetIME(imiId, mShortcutSubtype); switchToTargetIME(imiId, mShortcutSubtype, context);
} }
private void switchToTargetIME(final String imiId, final InputMethodSubtype subtype) { private void switchToTargetIME(final String imiId, final InputMethodSubtype subtype,
final IBinder token = mService.getWindow().getWindow().getAttributes().token; final InputMethodService context) {
final IBinder token = context.getWindow().getWindow().getAttributes().token;
if (token == null) { if (token == null) {
return; return;
} }
@ -253,7 +259,7 @@ public class SubtypeSwitcher {
return true; return true;
} }
public void onNetworkStateChanged(Intent intent) { public void onNetworkStateChanged(final Intent intent) {
final boolean noConnection = intent.getBooleanExtra( final boolean noConnection = intent.getBooleanExtra(
ConnectivityManager.EXTRA_NO_CONNECTIVITY, false); ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
mIsNetworkConnected = !noConnection; mIsNetworkConnected = !noConnection;
@ -265,7 +271,7 @@ public class SubtypeSwitcher {
// Subtype Switching functions // // Subtype Switching functions //
////////////////////////////////// //////////////////////////////////
public boolean needsToDisplayLanguage(Locale keyboardLocale) { public boolean needsToDisplayLanguage(final Locale keyboardLocale) {
if (keyboardLocale.toString().equals(SubtypeLocale.NO_LANGUAGE)) { if (keyboardLocale.toString().equals(SubtypeLocale.NO_LANGUAGE)) {
return true; return true;
} }
@ -279,12 +285,14 @@ public class SubtypeSwitcher {
return SubtypeLocale.getSubtypeLocale(mCurrentSubtype); return SubtypeLocale.getSubtypeLocale(mCurrentSubtype);
} }
public void onConfigurationChanged(Configuration conf) { public boolean onConfigurationChanged(final Configuration conf, final Context context) {
final Locale systemLocale = conf.locale; final Locale systemLocale = conf.locale;
final boolean systemLocaleChanged = !systemLocale.equals(mCurrentSystemLocale);
// If system configuration was changed, update all parameters. // If system configuration was changed, update all parameters.
if (!systemLocale.equals(mCurrentSystemLocale)) { if (systemLocaleChanged) {
updateAllParameters(); updateAllParameters(context);
} }
return systemLocaleChanged;
} }
public InputMethodSubtype getCurrentSubtype() { public InputMethodSubtype getCurrentSubtype() {

View File

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