diff options
Diffstat (limited to 'java/src')
12 files changed, 198 insertions, 153 deletions
diff --git a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java index ae614b7e0..7e71b5f36 100644 --- a/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java +++ b/java/src/com/android/inputmethod/accessibility/AccessibilityUtils.java @@ -16,7 +16,6 @@ package com.android.inputmethod.accessibility; -import android.accessibilityservice.AccessibilityServiceInfo; import android.content.Context; import android.content.SharedPreferences; import android.inputmethodservice.InputMethodService; @@ -82,10 +81,8 @@ public class AccessibilityUtils { */ public boolean isTouchExplorationEnabled() { return ENABLE_ACCESSIBILITY - && AccessibilityEventCompatUtils.supportsTouchExploration() && mAccessibilityManager.isEnabled() - && !mCompatManager.getEnabledAccessibilityServiceList( - AccessibilityServiceInfo.FEEDBACK_SPOKEN).isEmpty(); + && mCompatManager.isTouchExplorationEnabled(); } /** diff --git a/java/src/com/android/inputmethod/accessibility/AccessibleInputMethodServiceProxy.java b/java/src/com/android/inputmethod/accessibility/AccessibleInputMethodServiceProxy.java index 89adc15f2..4ab9cb898 100644 --- a/java/src/com/android/inputmethod/accessibility/AccessibleInputMethodServiceProxy.java +++ b/java/src/com/android/inputmethod/accessibility/AccessibleInputMethodServiceProxy.java @@ -47,6 +47,8 @@ public class AccessibleInputMethodServiceProxy implements AccessibleKeyboardActi */ private static final long VIBRATE_KEY_CLICK = 50; + private static final float FX_VOLUME = -1.0f; + private InputMethodService mInputMethod; private Vibrator mVibrator; private AudioManager mAudioManager; @@ -143,7 +145,7 @@ public class AccessibleInputMethodServiceProxy implements AccessibleKeyboardActi */ private void sendDownUpKeyEvents(int keyCode) { mVibrator.vibrate(VIBRATE_KEY_CLICK); - mAudioManager.playSoundEffect(AudioManager.FX_KEY_CLICK); + mAudioManager.playSoundEffect(AudioManager.FX_KEYPRESS_STANDARD, FX_VOLUME); mInputMethod.sendDownUpKeyEvents(keyCode); } diff --git a/java/src/com/android/inputmethod/compat/AccessibilityEventCompatUtils.java b/java/src/com/android/inputmethod/compat/AccessibilityEventCompatUtils.java index 50057727a..2fa9d87d8 100644 --- a/java/src/com/android/inputmethod/compat/AccessibilityEventCompatUtils.java +++ b/java/src/com/android/inputmethod/compat/AccessibilityEventCompatUtils.java @@ -16,24 +16,7 @@ package com.android.inputmethod.compat; -import android.view.accessibility.AccessibilityEvent; - -import java.lang.reflect.Field; - public class AccessibilityEventCompatUtils { public static final int TYPE_VIEW_HOVER_ENTER = 0x80; public static final int TYPE_VIEW_HOVER_EXIT = 0x100; - - private static final Field FIELD_TYPE_VIEW_HOVER_ENTER = CompatUtils.getField( - AccessibilityEvent.class, "TYPE_VIEW_HOVER_ENTER"); - private static final Field FIELD_TYPE_VIEW_HOVER_EXIT = CompatUtils.getField( - AccessibilityEvent.class, "TYPE_VIEW_HOVER_EXIT"); - private static final Integer OBJ_TYPE_VIEW_HOVER_ENTER = (Integer) CompatUtils - .getFieldValue(null, null, FIELD_TYPE_VIEW_HOVER_ENTER); - private static final Integer OBJ_TYPE_VIEW_HOVER_EXIT = (Integer) CompatUtils - .getFieldValue(null, null, FIELD_TYPE_VIEW_HOVER_EXIT); - - public static boolean supportsTouchExploration() { - return OBJ_TYPE_VIEW_HOVER_ENTER != null && OBJ_TYPE_VIEW_HOVER_EXIT != null; - } } diff --git a/java/src/com/android/inputmethod/compat/AccessibilityManagerCompatWrapper.java b/java/src/com/android/inputmethod/compat/AccessibilityManagerCompatWrapper.java index 4db1c7a24..a30af0faf 100644 --- a/java/src/com/android/inputmethod/compat/AccessibilityManagerCompatWrapper.java +++ b/java/src/com/android/inputmethod/compat/AccessibilityManagerCompatWrapper.java @@ -16,16 +16,13 @@ package com.android.inputmethod.compat; -import android.accessibilityservice.AccessibilityServiceInfo; import android.view.accessibility.AccessibilityManager; import java.lang.reflect.Method; -import java.util.Collections; -import java.util.List; public class AccessibilityManagerCompatWrapper { - private static final Method METHOD_getEnabledAccessibilityServiceList = CompatUtils.getMethod( - AccessibilityManager.class, "getEnabledAccessibilityServiceList", int.class); + private static final Method METHOD_isTouchExplorationEnabled = CompatUtils.getMethod( + AccessibilityManager.class, "isTouchExplorationEnabled"); private final AccessibilityManager mManager; @@ -33,10 +30,7 @@ public class AccessibilityManagerCompatWrapper { mManager = manager; } - @SuppressWarnings("unchecked") - public List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList(int feedbackType) { - return (List<AccessibilityServiceInfo>) CompatUtils.invoke(mManager, - Collections.<AccessibilityServiceInfo>emptyList(), - METHOD_getEnabledAccessibilityServiceList, feedbackType); + public boolean isTouchExplorationEnabled() { + return (Boolean) CompatUtils.invoke(mManager, false, METHOD_isTouchExplorationEnabled); } } diff --git a/java/src/com/android/inputmethod/deprecated/VoiceProxy.java b/java/src/com/android/inputmethod/deprecated/VoiceProxy.java index c82c570ee..9397483ce 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() { @@ -158,7 +158,10 @@ public class VoiceProxy implements VoiceInput.UiListener { } public void flushVoiceInputLogs(boolean configurationChanged) { - if (VOICE_INSTALLED && !configurationChanged) { + if (!VOICE_INSTALLED) { + return; + } + if (!configurationChanged) { if (mAfterVoiceInput) { mVoiceInput.flushAllTextModificationCounters(); mVoiceInput.logInputEnded(); @@ -170,6 +173,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. @@ -298,6 +304,9 @@ public class VoiceProxy implements VoiceInput.UiListener { } public void showPunctuationHintIfNecessary() { + if (!VOICE_INSTALLED) { + return; + } InputConnection ic = mService.getCurrentInputConnection(); if (!mImmediatelyAfterVoiceInput && mAfterVoiceInput && ic != null) { if (mHints.showPunctuationHintIfNecessary(ic)) { @@ -308,6 +317,9 @@ public class VoiceProxy implements VoiceInput.UiListener { } public void hideVoiceWindow(boolean configurationChanging) { + if (!VOICE_INSTALLED) { + return; + } if (!configurationChanging) { if (mAfterVoiceInput) mVoiceInput.logInputEnded(); @@ -324,6 +336,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); @@ -382,7 +397,10 @@ public class VoiceProxy implements VoiceInput.UiListener { } public boolean logAndRevertVoiceInput() { - if (VOICE_INSTALLED && mVoiceInputHighlighted) { + if (!VOICE_INSTALLED) { + return false; + } + if (mVoiceInputHighlighted) { mVoiceInput.incrementTextModificationDeleteCount( mVoiceResults.candidates.get(0).toString().length()); revertVoiceInput(); @@ -393,6 +411,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 +440,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 +472,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 +489,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 +500,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. @@ -478,13 +511,19 @@ public class VoiceProxy implements VoiceInput.UiListener { } public void handleClose() { - if (VOICE_INSTALLED & mRecognizing) { + if (!VOICE_INSTALLED) { + return; + } + if (mRecognizing) { mVoiceInput.cancel(); } } public void handleVoiceResults(boolean capitalizeFirstWord) { + if (!VOICE_INSTALLED) { + return; + } mAfterVoiceInput = true; mImmediatelyAfterVoiceInput = true; @@ -523,6 +562,9 @@ public class VoiceProxy implements VoiceInput.UiListener { } public void switchToRecognitionStatusView(final Configuration configuration) { + if (!VOICE_INSTALLED) { + return; + } mHandler.post(new Runnable() { @Override public void run() { @@ -567,6 +609,9 @@ public class VoiceProxy implements VoiceInput.UiListener { } private void switchToLastInputMethod() { + if (!VOICE_INSTALLED) { + return; + } final IBinder token = mService.getWindow().getWindow().getAttributes().token; new AsyncTask<Void, Void, Boolean>() { @Override @@ -632,14 +677,15 @@ public class VoiceProxy implements VoiceInput.UiListener { } public void startListening(final boolean swipe, IBinder token) { + if (!VOICE_INSTALLED) { + return; + } // TODO: remove swipe which is no longer used. - if (VOICE_INSTALLED) { - if (needsToShowWarningDialog()) { - // Calls reallyStartListening if user clicks OK, does nothing if user clicks Cancel. - showVoiceWarningDialog(swipe, token); - } else { - reallyStartListening(swipe); - } + if (needsToShowWarningDialog()) { + // Calls reallyStartListening if user clicks OK, does nothing if user clicks Cancel. + showVoiceWarningDialog(swipe, token); + } else { + reallyStartListening(swipe); } } @@ -659,7 +705,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); @@ -667,22 +720,26 @@ public class VoiceProxy implements VoiceInput.UiListener { mLocaleSupportedForVoiceInput = SubtypeSwitcher.getInstance().isVoiceSupported( SubtypeSwitcher.getInstance().getInputLocaleStr()); - if (VOICE_INSTALLED) { - final String voiceMode = sp.getString(PREF_VOICE_MODE, - mService.getString(R.string.voice_mode_main)); - mVoiceButtonEnabled = !voiceMode.equals(mService.getString(R.string.voice_mode_off)) - && shouldShowVoiceButton(makeFieldContext(), attribute); - mVoiceButtonOnPrimary = voiceMode.equals(mService.getString(R.string.voice_mode_main)); - } + final String voiceMode = sp.getString(PREF_VOICE_MODE, + mService.getString(R.string.voice_mode_main)); + mVoiceButtonEnabled = !voiceMode.equals(mService.getString(R.string.voice_mode_off)) + && shouldShowVoiceButton(makeFieldContext(), attribute); + mVoiceButtonOnPrimary = voiceMode.equals(mService.getString(R.string.voice_mode_main)); } public void destroy() { - if (VOICE_INSTALLED && mVoiceInput != null) { + if (!VOICE_INSTALLED) { + return; + } + if (mVoiceInput != null) { mVoiceInput.destroy(); } } 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 +756,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 +775,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 +799,9 @@ public class VoiceProxy implements VoiceInput.UiListener { @Override public void onVoiceResults(List<String> candidates, Map<String, List<CharSequence>> alternatives) { + if (!VOICE_INSTALLED) { + return; + } if (!mRecognizing) { return; } @@ -748,59 +817,22 @@ public class VoiceProxy implements VoiceInput.UiListener { switcher.getEnabledLanguages()); } - private class VoiceResults { + // TODO: make this private (proguard issue) + public static class VoiceResults { List<String> candidates; Map<String, List<CharSequence>> 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; } @@ -811,10 +843,16 @@ public class VoiceProxy implements VoiceInput.UiListener { } public void cancel() { + if (!VOICE_INSTALLED) { + return; + } if (mVoiceInput != null) mVoiceInput.cancel(); } public void reset() { + if (!VOICE_INSTALLED) { + return; + } if (mVoiceInput != null) mVoiceInput.reset(); } } diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java index cb1e759e4..088c9d140 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/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java index 4bda793b9..64bdc9591 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java @@ -132,6 +132,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy { @Override public void handleMessage(Message msg) { final KeyboardView keyboardView = getOuterInstance(); + if (keyboardView == null) return; final PointerTracker tracker = (PointerTracker) msg.obj; switch (msg.what) { case MSG_SHOW_KEY_PREVIEW: @@ -146,8 +147,9 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy { } public void showKeyPreview(long delay, int keyIndex, PointerTracker tracker) { - final KeyboardView keyboardView = getOuterInstance(); removeMessages(MSG_SHOW_KEY_PREVIEW); + final KeyboardView keyboardView = getOuterInstance(); + if (keyboardView == null) return; if (keyboardView.mPreviewText.getVisibility() == VISIBLE || delay == 0) { // Show right away, if it's already visible and finger is moving around keyboardView.showKey(keyIndex, tracker); diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParser.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParser.java index fcda91990..6f7349915 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardParser.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardParser.java @@ -632,15 +632,15 @@ public class KeyboardParser { private void endRow() { if (mCurrentRow == null) throw new InflateException("orphant end row tag"); + if (mRightEdgeKey != null) { + mRightEdgeKey.addEdgeFlags(Keyboard.EDGE_RIGHT); + mRightEdgeKey = null; + } setSpacer(mCurrentX, mHorizontalEdgesPadding); if (mCurrentX > mMaxRowWidth) mMaxRowWidth = mCurrentX; mCurrentY += mCurrentRow.mDefaultHeight; mCurrentRow = null; - if (mRightEdgeKey != null) { - mRightEdgeKey.addEdgeFlags(Keyboard.EDGE_RIGHT); - mRightEdgeKey = null; - } } private void endKey(Key key) { diff --git a/java/src/com/android/inputmethod/latin/DictionaryCollection.java b/java/src/com/android/inputmethod/latin/DictionaryCollection.java index e987d9f0c..107840331 100644 --- a/java/src/com/android/inputmethod/latin/DictionaryCollection.java +++ b/java/src/com/android/inputmethod/latin/DictionaryCollection.java @@ -17,6 +17,7 @@ package com.android.inputmethod.latin; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; @@ -36,11 +37,13 @@ public class DictionaryCollection extends Dictionary { mDictionaries = new CopyOnWriteArrayList<Dictionary>(); } else { mDictionaries = new CopyOnWriteArrayList<Dictionary>(dictionaries); + mDictionaries.removeAll(Collections.singleton(null)); } } public DictionaryCollection(Collection<Dictionary> dictionaries) { mDictionaries = new CopyOnWriteArrayList<Dictionary>(dictionaries); + mDictionaries.removeAll(Collections.singleton(null)); } @Override @@ -70,6 +73,6 @@ public class DictionaryCollection extends Dictionary { } public void addDictionary(Dictionary newDict) { - mDictionaries.add(newDict); + if (null != newDict) mDictionaries.add(newDict); } } diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index c5f7dd2c7..3457ac984 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -151,6 +151,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar private UserDictionary mUserDictionary; private UserBigramDictionary mUserBigramDictionary; private UserUnigramDictionary mUserUnigramDictionary; + private boolean mIsUserDictionaryAvaliable; // TODO: Create an inner class to group options and pseudo-options to improve readability. // These variables are initialized according to the {@link EditorInfo#inputType}. @@ -504,6 +505,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar mUserDictionary = new UserDictionary(this, localeStr); mSuggest.setUserDictionary(mUserDictionary); + mIsUserDictionaryAvaliable = mUserDictionary.isEnabled(); resetContactsDictionary(); @@ -645,9 +647,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(); } @@ -1763,7 +1763,11 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar // take a noticeable delay to update them which may feel uneasy. } if (showingAddToDictionaryHint) { - mCandidateView.showAddToDictionaryHint(suggestion); + if (mIsUserDictionaryAvaliable) { + mCandidateView.showAddToDictionaryHint(suggestion); + } else { + mHandler.postUpdateSuggestions(); + } } if (ic != null) { ic.endBatchEdit(); @@ -1966,9 +1970,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); - } } diff --git a/java/src/com/android/inputmethod/latin/UserDictionary.java b/java/src/com/android/inputmethod/latin/UserDictionary.java index 2aaa26c8d..f93d24fe6 100644 --- a/java/src/com/android/inputmethod/latin/UserDictionary.java +++ b/java/src/com/android/inputmethod/latin/UserDictionary.java @@ -38,23 +38,24 @@ public class UserDictionary extends ExpandableDictionary { Words.FREQUENCY, Words.LOCALE, }; - + private ContentObserver mObserver; private String mLocale; public UserDictionary(Context context, String locale) { super(context, Suggest.DIC_USER); mLocale = locale; - // Perform a managed query. The Activity will handle closing and requerying the cursor + // Perform a managed query. The Activity will handle closing and re-querying the cursor // when needed. ContentResolver cres = context.getContentResolver(); - - cres.registerContentObserver(Words.CONTENT_URI, true, mObserver = new ContentObserver(null) { + + mObserver = new ContentObserver(null) { @Override public void onChange(boolean self) { setRequiresReload(true); } - }); + }; + cres.registerContentObserver(Words.CONTENT_URI, true, mObserver); loadDictionary(); } @@ -76,6 +77,17 @@ public class UserDictionary extends ExpandableDictionary { addWords(cursor); } + public boolean isEnabled() { + final ContentResolver cr = getContext().getContentResolver(); + final ContentProviderClient client = cr.acquireContentProviderClient(Words.CONTENT_URI); + if (client != null) { + client.release(); + return true; + } else { + return false; + } + } + /** * Adds a word to the dictionary and makes it persistent. * @param word the word to add. If the word is capitalized, then the dictionary will |