diff --git a/java/src/com/android/inputmethod/deprecated/VoiceProxy.java b/java/src/com/android/inputmethod/deprecated/VoiceProxy.java index c82c570ee..b8a8169bc 100644 --- a/java/src/com/android/inputmethod/deprecated/VoiceProxy.java +++ b/java/src/com/android/inputmethod/deprecated/VoiceProxy.java @@ -17,11 +17,11 @@ package com.android.inputmethod.deprecated; import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; +import com.android.inputmethod.compat.InputMethodServiceCompatWrapper; import com.android.inputmethod.deprecated.voice.FieldContext; import com.android.inputmethod.deprecated.voice.Hints; import com.android.inputmethod.deprecated.voice.SettingsUtil; import com.android.inputmethod.deprecated.voice.VoiceInput; -import com.android.inputmethod.deprecated.voice.VoiceInputLogger; import com.android.inputmethod.keyboard.KeyboardSwitcher; import com.android.inputmethod.latin.EditingUtils; import com.android.inputmethod.latin.LatinIME; @@ -71,7 +71,8 @@ import java.util.Map; public class VoiceProxy implements VoiceInput.UiListener { private static final VoiceProxy sInstance = new VoiceProxy(); - public static final boolean VOICE_INSTALLED = true; + public static final boolean VOICE_INSTALLED = + !InputMethodServiceCompatWrapper.CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED; private static final boolean ENABLE_VOICE_BUTTON = true; private static final String PREF_VOICE_MODE = "voice_mode"; // Whether or not the user has used voice input before (and thus, whether to show the @@ -125,24 +126,23 @@ public class VoiceProxy implements VoiceInput.UiListener { } private void initInternal(LatinIME service, SharedPreferences prefs, UIHandler h) { + if (!VOICE_INSTALLED) { + return; + } mService = service; mHandler = h; mMinimumVoiceRecognitionViewHeightPixel = Utils.dipToPixel( Utils.getDipScale(service), RECOGNITIONVIEW_MINIMUM_HEIGHT_DIP); mImm = InputMethodManagerCompatWrapper.getInstance(); mSubtypeSwitcher = SubtypeSwitcher.getInstance(); - if (VOICE_INSTALLED) { - mVoiceInput = new VoiceInput(service, this); - mHints = new Hints(service, prefs, new Hints.Display() { - @Override - public void showHint(int viewResource) { - View view = LayoutInflater.from(mService).inflate(viewResource, null); -// mService.setCandidatesView(view); -// mService.setCandidatesViewShown(true); - mIsShowingHint = true; - } - }); - } + mVoiceInput = new VoiceInput(service, this); + mHints = new Hints(service, prefs, new Hints.Display() { + @Override + public void showHint(int viewResource) { + View view = LayoutInflater.from(mService).inflate(viewResource, null); + mIsShowingHint = true; + } + }); } private VoiceProxy() { @@ -170,6 +170,9 @@ public class VoiceProxy implements VoiceInput.UiListener { public void flushAndLogAllTextModificationCounters(int index, CharSequence suggestion, String wordSeparators) { + if (!VOICE_INSTALLED) { + return; + } if (mAfterVoiceInput && mShowingVoiceSuggestions) { mVoiceInput.flushAllTextModificationCounters(); // send this intent AFTER logging any prior aggregated edits. @@ -308,6 +311,9 @@ public class VoiceProxy implements VoiceInput.UiListener { } public void hideVoiceWindow(boolean configurationChanging) { + if (!VOICE_INSTALLED) { + return; + } if (!configurationChanging) { if (mAfterVoiceInput) mVoiceInput.logInputEnded(); @@ -324,6 +330,9 @@ public class VoiceProxy implements VoiceInput.UiListener { } public void setCursorAndSelection(int newSelEnd, int newSelStart) { + if (!VOICE_INSTALLED) { + return; + } if (mAfterVoiceInput) { mVoiceInput.setCursorPos(newSelEnd); mVoiceInput.setSelectionSpan(newSelEnd - newSelStart); @@ -366,6 +375,9 @@ public class VoiceProxy implements VoiceInput.UiListener { } private void revertVoiceInput() { + if (!VOICE_INSTALLED) { + return; + } InputConnection ic = mService.getCurrentInputConnection(); if (ic != null) ic.commitText("", 1); mService.updateSuggestions(); @@ -393,6 +405,9 @@ public class VoiceProxy implements VoiceInput.UiListener { } public void rememberReplacedWord(CharSequence suggestion,String wordSeparators) { + if (!VOICE_INSTALLED) { + return; + } if (mShowingVoiceSuggestions) { // Retain the replaced word in the alternatives array. String wordToBeReplaced = EditingUtils.getWordAtCursor( @@ -419,6 +434,9 @@ public class VoiceProxy implements VoiceInput.UiListener { * @return true if an alternative was found, false otherwise. */ public boolean applyVoiceAlternatives(EditingUtils.SelectedWord touching) { + if (!VOICE_INSTALLED) { + return false; + } // Search for result in spoken word alternatives String selectedWord = touching.mWord.toString().trim(); if (!mWordToSuggestions.containsKey(selectedWord)) { @@ -448,6 +466,9 @@ public class VoiceProxy implements VoiceInput.UiListener { } public void handleBackspace() { + if (!VOICE_INSTALLED) { + return; + } if (mAfterVoiceInput) { // Don't log delete if the user is pressing delete at // the beginning of the text box (hence not deleting anything) @@ -462,6 +483,9 @@ public class VoiceProxy implements VoiceInput.UiListener { } public void handleCharacter() { + if (!VOICE_INSTALLED) { + return; + } commitVoiceInput(); if (mAfterVoiceInput) { // Assume input length is 1. This assumption fails for smiley face insertions. @@ -470,6 +494,9 @@ public class VoiceProxy implements VoiceInput.UiListener { } public void handleSeparator() { + if (!VOICE_INSTALLED) { + return; + } commitVoiceInput(); if (mAfterVoiceInput){ // Assume input length is 1. This assumption fails for smiley face insertions. @@ -485,6 +512,9 @@ public class VoiceProxy implements VoiceInput.UiListener { public void handleVoiceResults(boolean capitalizeFirstWord) { + if (!VOICE_INSTALLED) { + return; + } mAfterVoiceInput = true; mImmediatelyAfterVoiceInput = true; @@ -659,7 +689,14 @@ public class VoiceProxy implements VoiceInput.UiListener { && SpeechRecognizer.isRecognitionAvailable(mService); } + public static boolean isRecognitionAvailable(Context context) { + return SpeechRecognizer.isRecognitionAvailable(context); + } + public void loadSettings(EditorInfo attribute, SharedPreferences sp) { + if (!VOICE_INSTALLED) { + return; + } mHasUsedVoiceInput = sp.getBoolean(PREF_HAS_USED_VOICE_INPUT, false); mHasUsedVoiceInputUnsupportedLocale = sp.getBoolean(PREF_HAS_USED_VOICE_INPUT_UNSUPPORTED_LOCALE, false); @@ -683,6 +720,9 @@ public class VoiceProxy implements VoiceInput.UiListener { } public void onStartInputView(IBinder keyboardViewToken) { + if (!VOICE_INSTALLED) { + return; + } // If keyboardViewToken is null, keyboardView is not attached but voiceView is attached. IBinder windowToken = keyboardViewToken != null ? keyboardViewToken : mVoiceInput.getView().getWindowToken(); @@ -699,12 +739,18 @@ public class VoiceProxy implements VoiceInput.UiListener { } public void onAttachedToWindow() { + if (!VOICE_INSTALLED) { + return; + } // After onAttachedToWindow, we can show the voice warning dialog. See startListening() // above. VoiceInputWrapper.getInstance().setVoiceInput(mVoiceInput, mSubtypeSwitcher); } public void onConfigurationChanged(Configuration configuration) { + if (!VOICE_INSTALLED) { + return; + } if (mRecognizing) { switchToRecognitionStatusView(configuration); } @@ -712,6 +758,9 @@ public class VoiceProxy implements VoiceInput.UiListener { @Override public void onCancelVoice() { + if (!VOICE_INSTALLED) { + return; + } if (mRecognizing) { if (mSubtypeSwitcher.isVoiceMode()) { // If voice mode is being canceled within LatinIME (i.e. time-out or user @@ -733,6 +782,9 @@ public class VoiceProxy implements VoiceInput.UiListener { @Override public void onVoiceResults(List candidates, Map> alternatives) { + if (!VOICE_INSTALLED) { + return; + } if (!mRecognizing) { return; } @@ -748,59 +800,22 @@ public class VoiceProxy implements VoiceInput.UiListener { switcher.getEnabledLanguages()); } - private class VoiceResults { + // TODO: make this private (proguard issue) + public static class VoiceResults { List candidates; Map> alternatives; } - public static class VoiceLoggerWrapper { - private static final VoiceLoggerWrapper sLoggerWrapperInstance = new VoiceLoggerWrapper(); - private VoiceInputLogger mLogger; - - public static VoiceLoggerWrapper getInstance(Context context) { - if (sLoggerWrapperInstance.mLogger == null) { - // Not thread safe, but it's ok. - sLoggerWrapperInstance.mLogger = VoiceInputLogger.getLogger(context); - } - return sLoggerWrapperInstance; - } - - // private for the singleton - private VoiceLoggerWrapper() { - } - - public void settingsWarningDialogCancel() { - mLogger.settingsWarningDialogCancel(); - } - - public void settingsWarningDialogOk() { - mLogger.settingsWarningDialogOk(); - } - - public void settingsWarningDialogShown() { - mLogger.settingsWarningDialogShown(); - } - - public void settingsWarningDialogDismissed() { - mLogger.settingsWarningDialogDismissed(); - } - - public void voiceInputSettingEnabled(boolean enabled) { - if (enabled) { - mLogger.voiceInputSettingEnabled(); - } else { - mLogger.voiceInputSettingDisabled(); - } - } - } - public static class VoiceInputWrapper { private static final VoiceInputWrapper sInputWrapperInstance = new VoiceInputWrapper(); private VoiceInput mVoiceInput; public static VoiceInputWrapper getInstance() { return sInputWrapperInstance; } - public void setVoiceInput(VoiceInput voiceInput, SubtypeSwitcher switcher) { + private void setVoiceInput(VoiceInput voiceInput, SubtypeSwitcher switcher) { + if (!VOICE_INSTALLED) { + return; + } if (mVoiceInput == null && voiceInput != null) { mVoiceInput = voiceInput; } diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java index 37c501468..52ecfe236 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java @@ -148,11 +148,11 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha } } - public void loadKeyboard(EditorInfo attribute, boolean voiceKeyEnabled, - boolean voiceButtonOnPrimary) { + public void loadKeyboard(EditorInfo attribute, Settings.Values settings) { mSwitchState = SWITCH_STATE_ALPHA; try { - loadKeyboardInternal(attribute, voiceKeyEnabled, voiceButtonOnPrimary, false); + loadKeyboardInternal(attribute, settings.isVoiceButtonEnabled(attribute), + settings.isVoiceButtonOnPrimary(), false); } catch (RuntimeException e) { // Get KeyboardId to record which keyboard has been failed to load. final KeyboardId id = getKeyboardId(attribute, false); diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 1364c4a54..324a13045 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -575,9 +575,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar LanguageSwitcherProxy.loadSettings(); if (mSubtypeSwitcher.isKeyboardMode()) { - switcher.loadKeyboard(attribute, - mSubtypeSwitcher.isShortcutImeEnabled() && voiceIme.isVoiceButtonEnabled(), - voiceIme.isVoiceButtonOnPrimary()); + switcher.loadKeyboard(attribute, mSettingsValues); switcher.updateShiftState(); } @@ -1900,9 +1898,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar setInputView(mKeyboardSwitcher.onCreateInputView()); } // Reload keyboard because the current language has been changed. - mKeyboardSwitcher.loadKeyboard(getCurrentInputEditorInfo(), - mSubtypeSwitcher.isShortcutImeEnabled() && mVoiceProxy.isVoiceButtonEnabled(), - mVoiceProxy.isVoiceButtonOnPrimary()); + mKeyboardSwitcher.loadKeyboard(getCurrentInputEditorInfo(), mSettingsValues); initSuggest(); loadSettings(); mKeyboardSwitcher.updateShiftState(); diff --git a/java/src/com/android/inputmethod/latin/Settings.java b/java/src/com/android/inputmethod/latin/Settings.java index 54f0a1b4d..b6171d276 100644 --- a/java/src/com/android/inputmethod/latin/Settings.java +++ b/java/src/com/android/inputmethod/latin/Settings.java @@ -16,13 +16,6 @@ package com.android.inputmethod.latin; -import com.android.inputmethod.compat.CompatUtils; -import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; -import com.android.inputmethod.compat.InputMethodServiceCompatWrapper; -import com.android.inputmethod.deprecated.VoiceProxy; -import com.android.inputmethod.compat.VibratorCompatWrapper; -import com.android.inputmethodcommon.InputMethodSettingsActivity; - import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; @@ -40,12 +33,20 @@ import android.preference.Preference; import android.preference.Preference.OnPreferenceClickListener; import android.preference.PreferenceGroup; import android.preference.PreferenceScreen; -import android.speech.SpeechRecognizer; import android.text.TextUtils; import android.text.method.LinkMovementMethod; import android.util.Log; +import android.view.inputmethod.EditorInfo; import android.widget.TextView; +import com.android.inputmethod.compat.CompatUtils; +import com.android.inputmethod.compat.InputMethodManagerCompatWrapper; +import com.android.inputmethod.compat.InputMethodServiceCompatWrapper; +import com.android.inputmethod.compat.InputTypeCompatUtils; +import com.android.inputmethod.compat.VibratorCompatWrapper; +import com.android.inputmethod.deprecated.VoiceProxy; +import com.android.inputmethodcommon.InputMethodSettingsActivity; + import java.util.Arrays; import java.util.Locale; @@ -119,6 +120,9 @@ public class Settings extends InputMethodSettingsActivity public final boolean mBigramPredictionEnabled; public final boolean mUseContactsDict; + private final boolean mVoiceButtonEnabled; + private final boolean mVoiceButtonOnPrimary; + public Values(final SharedPreferences prefs, final Context context, final String localeStr) { final Resources res = context.getResources(); @@ -179,6 +183,12 @@ public class Settings extends InputMethodSettingsActivity mUseContactsDict = prefs.getBoolean(Settings.PREF_KEY_USE_CONTACTS_DICT, true); + final String voiceMode = prefs.getString(PREF_VOICE_SETTINGS_KEY, null); + mVoiceButtonEnabled = voiceMode != null && !voiceMode.equals( + res.getString(R.string.voice_mode_off)); + mVoiceButtonOnPrimary = voiceMode != null && voiceMode.equals( + res.getString(R.string.voice_mode_main)); + Utils.setSystemLocale(res, savedLocale); } @@ -287,6 +297,17 @@ public class Settings extends InputMethodSettingsActivity } return builder.setIsPunctuationSuggestions().build(); } + + public boolean isVoiceButtonEnabled(EditorInfo attribute) { + final boolean shortcutImeEnabled = SubtypeSwitcher.getInstance().isShortcutImeEnabled(); + final int inputType = (attribute != null) ? attribute.inputType : 0; + return shortcutImeEnabled && mVoiceButtonEnabled + && !InputTypeCompatUtils.isPasswordInputType(inputType); + } + + public boolean isVoiceButtonOnPrimary() { + return mVoiceButtonOnPrimary; + } } private PreferenceScreen mInputLanguageSelection; @@ -304,8 +325,6 @@ public class Settings extends InputMethodSettingsActivity private AlertDialog mDialog; - private VoiceProxy.VoiceLoggerWrapper mVoiceLogger; - private boolean mOkClicked = false; private String mVoiceModeOff; @@ -349,7 +368,6 @@ public class Settings extends InputMethodSettingsActivity mVoiceModeOff = getString(R.string.voice_mode_off); mVoiceOn = !(prefs.getString(PREF_VOICE_SETTINGS_KEY, mVoiceModeOff) .equals(mVoiceModeOff)); - mVoiceLogger = VoiceProxy.VoiceLoggerWrapper.getInstance(context); mAutoCorrectionThreshold = (ListPreference) findPreference(PREF_AUTO_CORRECTION_THRESHOLD); mBigramSuggestion = (CheckBoxPreference) findPreference(PREF_BIGRAM_SUGGESTIONS); @@ -447,14 +465,17 @@ public class Settings extends InputMethodSettingsActivity } } + @SuppressWarnings("unused") @Override public void onResume() { super.onResume(); - if (!VoiceProxy.VOICE_INSTALLED - || !SpeechRecognizer.isRecognitionAvailable(getActivityInternal())) { - getPreferenceScreen().removePreference(mVoicePreference); - } else { + final boolean isShortcutImeEnabled = SubtypeSwitcher.getInstance().isShortcutImeEnabled(); + if (isShortcutImeEnabled + || (VoiceProxy.VOICE_INSTALLED + && VoiceProxy.isRecognitionAvailable(getActivityInternal()))) { updateVoiceModeSummary(); + } else { + getPreferenceScreen().removePreference(mVoicePreference); } updateSettingsKeySummary(); updateShowCorrectionSuggestionsSummary(); @@ -541,6 +562,7 @@ public class Settings extends InputMethodSettingsActivity [mVoicePreference.findIndexOfValue(mVoicePreference.getValue())]); } + @Override protected Dialog onCreateDialog(int id) { switch (id) { case VOICE_INPUT_CONFIRM_DIALOG: @@ -549,12 +571,9 @@ public class Settings extends InputMethodSettingsActivity public void onClick(DialogInterface dialog, int whichButton) { if (whichButton == DialogInterface.BUTTON_NEGATIVE) { mVoicePreference.setValue(mVoiceModeOff); - mVoiceLogger.settingsWarningDialogCancel(); } else if (whichButton == DialogInterface.BUTTON_POSITIVE) { mOkClicked = true; - mVoiceLogger.settingsWarningDialogOk(); } - updateVoicePreference(); } }; AlertDialog.Builder builder = new AlertDialog.Builder(getActivityInternal()) @@ -583,7 +602,6 @@ public class Settings extends InputMethodSettingsActivity AlertDialog dialog = builder.create(); mDialog = dialog; dialog.setOnDismissListener(this); - mVoiceLogger.settingsWarningDialogShown(); return dialog; default: Log.e(TAG, "unknown dialog " + id); @@ -593,16 +611,10 @@ public class Settings extends InputMethodSettingsActivity @Override public void onDismiss(DialogInterface dialog) { - mVoiceLogger.settingsWarningDialogDismissed(); if (!mOkClicked) { // This assumes that onPreferenceClick gets called first, and this if the user // agreed after the warning, we set the mOkClicked value to true. mVoicePreference.setValue(mVoiceModeOff); } } - - private void updateVoicePreference() { - boolean isChecked = !mVoicePreference.getValue().equals(mVoiceModeOff); - mVoiceLogger.voiceInputSettingEnabled(isChecked); - } }