Enabled to change the current subtype to voice input subtypes

bug: 3201828

Change-Id: I4450cbc8ba8829060d702564889c735f1326cf23
main
satok 2010-11-21 12:43:10 +09:00
parent 0b60f83192
commit 8e09172df1
3 changed files with 154 additions and 26 deletions

View File

@ -35,6 +35,7 @@ import android.inputmethodservice.InputMethodService;
import android.media.AudioManager;
import android.os.Debug;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.SystemClock;
import android.os.Vibrator;
@ -48,6 +49,8 @@ import android.util.Printer;
import android.view.HapticFeedbackConstants;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.CompletionInfo;
@ -458,7 +461,7 @@ public class LatinIME extends InputMethodService
@Override
public void onConfigurationChanged(Configuration conf) {
mSubtypeSwitcher.onConfigurationChanged(conf);
onLanguageChanged();
onKeyboardLanguageChanged();
updateAutoTextEnabled();
// If orientation changed while predicting, commit the change
@ -512,6 +515,7 @@ public class LatinIME extends InputMethodService
public void onStartInputView(EditorInfo attribute, boolean restarting) {
final KeyboardSwitcher switcher = mKeyboardSwitcher;
LatinKeyboardView inputView = switcher.getInputView();
// In landscape mode, this method gets called without the input view being created.
if (inputView == null) {
return;
@ -521,7 +525,7 @@ public class LatinIME extends InputMethodService
if (mRefreshKeyboardRequired) {
mRefreshKeyboardRequired = false;
onLanguageChanged();
onKeyboardLanguageChanged();
}
TextEntryState.newSession(this);
@ -629,6 +633,10 @@ public class LatinIME extends InputMethodService
checkReCorrectionOnStart();
checkTutorial(attribute.privateImeOptions);
inputView.setForeground(true);
// TODO: Not to show keyboard if IME starts in Voice One shot mode.
mVoiceConnector.onStartInputView();
if (TRACE) Debug.startMethodTracing("/data/trace/latinime");
}
@ -709,10 +717,8 @@ public class LatinIME extends InputMethodService
// If the current selection in the text view changes, we should
// clear whatever candidate text we have.
if ((((mComposing.length() > 0 && mPredicting)
|| mVoiceConnector.isVoiceInputHighlighted())
&& (newSelStart != candidatesEnd
|| newSelEnd != candidatesEnd)
&& mLastSelectionStart != newSelStart)) {
|| mVoiceConnector.isVoiceInputHighlighted()) && (newSelStart != candidatesEnd
|| newSelEnd != candidatesEnd) && mLastSelectionStart != newSelStart)) {
mComposing.setLength(0);
mPredicting = false;
mHandler.postUpdateSuggestions();
@ -1418,8 +1424,17 @@ public class LatinIME extends InputMethodService
public void switchToKeyboardView() {
mHandler.post(new Runnable() {
public void run() {
if (mKeyboardSwitcher.getInputView() != null) {
setInputView(mKeyboardSwitcher.getInputView());
if (DEBUG) {
Log.d(TAG, "Switch to keyboard view.");
}
View v = mKeyboardSwitcher.getInputView();
if (v != null) {
// Confirms that the keyboard view doesn't have parent view.
ViewParent p = v.getParent();
if (p != null && p instanceof ViewGroup) {
((ViewGroup)p).removeView(v);
}
setInputView(v);
}
setCandidatesViewShown(isCandidateStripVisible());
updateInputViewShown();
@ -1844,7 +1859,7 @@ public class LatinIME extends InputMethodService
// Notify that Language has been changed and toggleLanguage will update KeyboaredID according
// to new Language.
private void onLanguageChanged() {
public void onKeyboardLanguageChanged() {
toggleLanguage(true, true);
}
@ -2226,6 +2241,5 @@ public class LatinIME extends InputMethodService
@Override
public void onCurrentInputMethodSubtypeChanged(InputMethodSubtype subtype) {
SubtypeSwitcher.getInstance().updateSubtype(subtype);
onLanguageChanged();
}
}

View File

@ -17,12 +17,12 @@
package com.android.inputmethod.latin;
import com.android.inputmethod.voice.SettingsUtil;
import com.android.inputmethod.voice.VoiceInput;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.inputmethodservice.InputMethodService;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import android.util.Log;
@ -39,7 +39,7 @@ public class SubtypeSwitcher {
// We may or may not draw the current language on space bar regardless of this flag.
public static final boolean USE_SPACEBAR_LANGUAGE_SWITCHER = false;
private static final boolean DBG = false;
private static final String TAG = "SubtypeSwitcher";
private static final String TAG = "InputMethodSubtypeSwitcher";
private static final char LOCALE_SEPARATER = '_';
private static final String KEYBOARD_MODE = "keyboard";
@ -48,7 +48,7 @@ public class SubtypeSwitcher {
new TextUtils.SimpleStringSplitter(LOCALE_SEPARATER);
private static final SubtypeSwitcher sInstance = new SubtypeSwitcher();
private /* final */ InputMethodService mService;
private /* final */ LatinIME mService;
private /* final */ InputMethodManager mImm;
private /* final */ Resources mResources;
private final ArrayList<InputMethodSubtype> mEnabledKeyboardSubtypesOfCurrentInputMethod =
@ -62,6 +62,7 @@ public class SubtypeSwitcher {
private String mInputLocaleStr;
private String mMode;
private List<InputMethodSubtype> mAllEnabledSubtypesOfCurrentInputMethod;
private VoiceInput mVoiceInput;
private boolean mNeedsToDisplayLanguage;
private boolean mIsSystemLanguageSameAsInputLanguage;
/*-----------------------------------------------------------*/
@ -71,10 +72,7 @@ public class SubtypeSwitcher {
}
public static void init(LatinIME service) {
sInstance.mService = service;
sInstance.mResources = service.getResources();
sInstance.mImm = (InputMethodManager) service.getSystemService(
Context.INPUT_METHOD_SERVICE);
sInstance.resetParams(service);
if (USE_SPACEBAR_LANGUAGE_SWITCHER) {
sInstance.initLanguageSwitcher(service);
}
@ -85,6 +83,21 @@ public class SubtypeSwitcher {
private SubtypeSwitcher() {
}
private void resetParams(LatinIME service) {
mService = service;
mResources = service.getResources();
mImm = (InputMethodManager) service.getSystemService(Context.INPUT_METHOD_SERVICE);
mEnabledKeyboardSubtypesOfCurrentInputMethod.clear();
mEnabledLanguagesOfCurrentInputMethod.clear();
mSystemLocale = null;
mInputLocale = null;
mInputLocaleStr = null;
mMode = null;
mAllEnabledSubtypesOfCurrentInputMethod = null;
// TODO: Voice input should be created here
mVoiceInput = null;
}
// Update all parameters stored in SubtypeSwitcher.
// Only configuration changed event is allowed to call this because this is heavy.
private void updateAllParameters() {
@ -126,17 +139,65 @@ public class SubtypeSwitcher {
mNeedsToDisplayLanguage = !(getEnabledKeyboardLocaleCount() <= 1
&& mIsSystemLanguageSameAsInputLanguage);
if (foundCurrentSubtypeBecameDisabled) {
if (DBG) {
Log.w(TAG, "Last subtype was disabled. Update to the current one.");
}
updateSubtype(mImm.getCurrentInputMethodSubtype());
}
}
// Update the current subtype. LatinIME.onCurrentInputMethodSubtypeChanged calls this function.
public void updateSubtype(InputMethodSubtype newSubtype) {
if (DBG) {
Log.w(TAG, "Update subtype to:" + newSubtype.getLocale() + "," + newSubtype.getMode());
final String newLocale;
final String newMode;
if (newSubtype == null) {
// Normally, newSubtype shouldn't be null. But just in case if newSubtype was null,
// fallback to the default locale and mode.
Log.e(TAG, "Couldn't get the current subtype.");
newLocale = "en_US";
newMode =KEYBOARD_MODE;
} else {
newLocale = newSubtype.getLocale();
newMode = newSubtype.getMode();
}
if (DBG) {
Log.w(TAG, "Update subtype to:" + newLocale + "," + newMode
+ ", from: " + mInputLocaleStr + ", " + mMode);
}
boolean languageChanged = false;
if (!newLocale.equals(mInputLocaleStr)) {
if (mInputLocaleStr != null) {
languageChanged = true;
}
updateInputLocale(newLocale);
}
boolean modeChanged = false;
String oldMode = mMode;
if (!newMode.equals(mMode)) {
if (mMode != null) {
modeChanged = true;
}
mMode = newMode;
}
if (isKeyboardMode()) {
if (modeChanged) {
if (VOICE_MODE.equals(oldMode) && mVoiceInput != null) {
mVoiceInput.cancel();
}
}
if (languageChanged) {
mService.onKeyboardLanguageChanged();
}
} else if (isVoiceMode()) {
if (languageChanged || modeChanged) {
if (mVoiceInput != null) {
// TODO: Call proper function to trigger VoiceIME
mService.onKey(LatinKeyboardView.KEYCODE_VOICE, null, 0, 0);
}
}
} else {
Log.w(TAG, "Unknown subtype mode: " + mMode);
}
updateInputLocale(newSubtype.getLocale());
mMode = newSubtype.getMode();
}
// Update the current input locale from Locale string.
@ -269,6 +330,37 @@ public class SubtypeSwitcher {
return oldLocale;
}
public boolean isKeyboardMode() {
return KEYBOARD_MODE.equals(mMode);
}
///////////////////////////
// Voice Input functions //
///////////////////////////
public boolean setVoiceInput(VoiceInput vi) {
if (mVoiceInput == null) {
// TODO: Remove requirements to construct KeyboardSwitcher
// when IME was enabled with Voice mode
mService.onKeyboardLanguageChanged();
mVoiceInput = vi;
if (isVoiceMode() && mVoiceInput != null) {
if (DBG) {
Log.d(TAG, "Set and call voice input.");
}
// TODO: Call proper function to enable VoiceIME
mService.onKey(LatinKeyboardView.KEYCODE_VOICE, null, 0, 0);
return true;
}
}
return false;
}
public boolean isVoiceMode() {
return VOICE_MODE.equals(mMode);
}
//////////////////////////////////////
// SpaceBar Language Switch support //
//////////////////////////////////////
@ -383,4 +475,4 @@ public class SubtypeSwitcher {
mLanguageSwitcher.loadLocales(prefs);
mLanguageSwitcher.setSystemLocale(conf.locale);
}
}
}

View File

@ -41,6 +41,7 @@ import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import java.util.ArrayList;
import java.util.HashMap;
@ -78,12 +79,14 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
private boolean mVoiceButtonOnPrimary;
private boolean mVoiceInputHighlighted;
private InputMethodManager mImm;
private LatinIME mContext;
private AlertDialog mVoiceWarningDialog;
private VoiceInput mVoiceInput;
private final VoiceResults mVoiceResults = new VoiceResults();
private Hints mHints;
private UIHandler mHandler;
private SubtypeSwitcher mSubtypeSwitcher;
// For each word, a list of potential replacements, usually from voice.
private final Map<String, List<CharSequence>> mWordToSuggestions =
new HashMap<String, List<CharSequence>>();
@ -96,6 +99,8 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
private void initInternal(LatinIME context, UIHandler h) {
mContext = context;
mHandler = h;
mImm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
mSubtypeSwitcher = SubtypeSwitcher.getInstance();
if (VOICE_INSTALLED) {
mVoiceInput = new VoiceInput(context, this);
mHints = new Hints(context, new Hints.Display() {
@ -376,7 +381,6 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
}
}
mContext.vibrate();
mContext.switchToKeyboardView();
final List<CharSequence> nBest = new ArrayList<CharSequence>();
for (String c : mVoiceResults.candidates) {
@ -399,6 +403,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
mVoiceInputHighlighted = true;
mWordToSuggestions.putAll(mVoiceResults.alternatives);
onCancelVoice();
}
public void switchToRecognitionStatusView(final boolean configurationChanging) {
@ -410,7 +415,7 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
View v = mVoiceInput.getView();
ViewParent p = v.getParent();
if (p != null && p instanceof ViewGroup) {
((ViewGroup)v.getParent()).removeView(v);
((ViewGroup)p).removeView(v);
}
mContext.setInputView(v);
mContext.updateInputViewShown();
@ -499,6 +504,10 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
}
}
public void onStartInputView() {
mSubtypeSwitcher.setVoiceInput(mVoiceInput);
}
public void onConfigurationChanged(boolean configurationChanging) {
if (mRecognizing) {
switchToRecognitionStatusView(configurationChanging);
@ -507,8 +516,21 @@ public class VoiceIMEConnector implements VoiceInput.UiListener {
@Override
public void onCancelVoice() {
if (mRecognizing) {
mRecognizing = false;
mContext.switchToKeyboardView();
if (mSubtypeSwitcher.isVoiceMode()) {
// If voice mode is being canceled within LatinIME (i.e. time-out or user
// cancellation etc.), onCancelVoice() will be called first. LatinIME thinks it's
// still in voice mode. LatinIME needs to call switchToLastInputMethod().
// Note that onCancelVoice() will be called again from SubtypeSwitcher.
IBinder token = mContext.getWindow().getWindow().getAttributes().token;
mImm.switchToLastInputMethod(token);
} else if (mSubtypeSwitcher.isKeyboardMode()) {
// If voice mode is being canceled out of LatinIME (i.e. by user's IME switching or
// as a result of switchToLastInputMethod() etc.),
// onCurrentInputMethodSubtypeChanged() will be called first. LatinIME will know
// that it's in keyboard mode and SubtypeSwitcher will call onCancelVoice().
mRecognizing = false;
mContext.switchToKeyboardView();
}
}
}