Enabled to change the current subtype to voice input subtypes
bug: 3201828 Change-Id: I4450cbc8ba8829060d702564889c735f1326cf23main
parent
0b60f83192
commit
8e09172df1
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue