diff options
Diffstat (limited to 'java')
10 files changed, 162 insertions, 217 deletions
diff --git a/java/src/com/android/inputmethod/compat/AbstractCompatWrapper.java b/java/src/com/android/inputmethod/compat/AbstractCompatWrapper.java index 65949357f..2c31c55b0 100644 --- a/java/src/com/android/inputmethod/compat/AbstractCompatWrapper.java +++ b/java/src/com/android/inputmethod/compat/AbstractCompatWrapper.java @@ -24,7 +24,7 @@ public abstract class AbstractCompatWrapper { public AbstractCompatWrapper(Object obj) { if (obj == null) { - Log.e(TAG, "Invalid input to AbstructCompatWrapper"); + Log.e(TAG, "Invalid input to AbstractCompatWrapper"); } mObj = obj; } diff --git a/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatWrapper.java index a6bb83adf..574158825 100644 --- a/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatWrapper.java +++ b/java/src/com/android/inputmethod/compat/InputMethodSubtypeCompatWrapper.java @@ -29,7 +29,7 @@ import java.util.Locale; // TODO: Override this class with the concrete implementation if we need to take care of the // performance. -public final class InputMethodSubtypeCompatWrapper extends AbstractCompatWrapper { +public class InputMethodSubtypeCompatWrapper extends AbstractCompatWrapper { private static final boolean DBG = LatinImeLogger.sDBG; private static final String TAG = InputMethodSubtypeCompatWrapper.class.getSimpleName(); private static final String DEFAULT_LOCALE = "en_US"; @@ -65,7 +65,7 @@ public final class InputMethodSubtypeCompatWrapper extends AbstractCompatWrapper public InputMethodSubtypeCompatWrapper(Object subtype) { super((CLASS_InputMethodSubtype != null && CLASS_InputMethodSubtype.isInstance(subtype)) - ? subtype : null); + ? subtype : new Object()); mDummyNameResId = 0; mDummyIconResId = 0; mDummyLocale = DEFAULT_LOCALE; @@ -76,7 +76,7 @@ public final class InputMethodSubtypeCompatWrapper extends AbstractCompatWrapper // Constructor for creating a dummy subtype. public InputMethodSubtypeCompatWrapper(int nameResId, int iconResId, String locale, String mode, String extraValues) { - super(null); + super(new Object()); if (DBG) { Log.d(TAG, "CreateInputMethodSubtypeCompatWrapper"); } diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java index 5660d1942..320b1bea2 100644 --- a/java/src/com/android/inputmethod/keyboard/Keyboard.java +++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java @@ -388,6 +388,7 @@ public class Keyboard { } } + // TODO: Move this method to KeyboardSwitcher. public static String toThemeName(int themeId) { // This should be aligned with theme-*.xml resource files' themeId attribute. switch (themeId) { diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java index ac8dd1b95..efe5aa9cf 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java @@ -39,8 +39,7 @@ import com.android.inputmethod.latin.SettingsValues; import com.android.inputmethod.latin.SubtypeSwitcher; import com.android.inputmethod.latin.Utils; -public class KeyboardSwitcher implements KeyboardState.SwitchActions, - SharedPreferences.OnSharedPreferenceChangeListener { +public class KeyboardSwitcher implements KeyboardState.SwitchActions { private static final String TAG = KeyboardSwitcher.class.getSimpleName(); public static final String PREF_KEYBOARD_LAYOUT = "pref_keyboard_layout_20110916"; @@ -94,7 +93,6 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions, mSubtypeSwitcher = SubtypeSwitcher.getInstance(); mState = new KeyboardState(this); setContextThemeWrapper(ims, getKeyboardThemeIndex(ims, prefs)); - prefs.registerOnSharedPreferenceChangeListener(this); mForceNonDistinctMultitouch = prefs.getBoolean( DebugSettings.FORCE_NON_DISTINCT_MULTITOUCH_KEY, false); } @@ -341,34 +339,26 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions, } public View onCreateInputView() { - return createInputView(mThemeIndex, true); - } - - private View createInputView(final int newThemeIndex, final boolean forceRecreate) { - if (mCurrentInputView != null && mThemeIndex == newThemeIndex && !forceRecreate) - return mCurrentInputView; - if (mKeyboardView != null) { mKeyboardView.closing(); } - final int oldThemeIndex = mThemeIndex; Utils.GCUtils.getInstance().reset(); boolean tryGC = true; for (int i = 0; i < Utils.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) { try { - setContextThemeWrapper(mInputMethodService, newThemeIndex); + setContextThemeWrapper(mInputMethodService, mThemeIndex); mCurrentInputView = (InputView)LayoutInflater.from(mThemeContext).inflate( R.layout.input_view, null); tryGC = false; } catch (OutOfMemoryError e) { Log.w(TAG, "load keyboard failed: " + e); tryGC = Utils.GCUtils.getInstance().tryGCOrWait( - oldThemeIndex + "," + newThemeIndex, e); + Keyboard.toThemeName(mThemeIndex), e); } catch (InflateException e) { Log.w(TAG, "load keyboard failed: " + e); tryGC = Utils.GCUtils.getInstance().tryGCOrWait( - oldThemeIndex + "," + newThemeIndex, e); + Keyboard.toThemeName(mThemeIndex), e); } } @@ -385,27 +375,6 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions, return mCurrentInputView; } - private void postSetInputView(final View newInputView) { - final LatinIME latinIme = mInputMethodService; - latinIme.mHandler.post(new Runnable() { - @Override - public void run() { - if (newInputView != null) { - latinIme.setInputView(newInputView); - } - latinIme.updateInputViewShown(); - } - }); - } - - @Override - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { - if (PREF_KEYBOARD_LAYOUT.equals(key)) { - final int themeIndex = getKeyboardThemeIndex(mInputMethodService, sharedPreferences); - postSetInputView(createInputView(themeIndex, false)); - } - } - public void onNetworkStateChanged() { if (mKeyboardView != null) { mKeyboardView.updateShortcutKey(SubtypeSwitcher.getInstance().isShortcutImeReady()); diff --git a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java index f96f71e8a..721ea135f 100644 --- a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java +++ b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java @@ -44,10 +44,11 @@ public class ProximityInfo { // TODO: Find a proper name for mKeyboardMinWidth private final int mKeyboardMinWidth; private final int mKeyboardHeight; + private final int mMostCommonKeyWidth; private final Key[][] mGridNeighbors; - ProximityInfo(int gridWidth, int gridHeight, int minWidth, int height, int keyWidth, - int keyHeight, Set<Key> keys, TouchPositionCorrection touchPositionCorrection, + ProximityInfo(int gridWidth, int gridHeight, int minWidth, int height, int mostCommonKeyWidth, + int mostCommonKeyHeight, Set<Key> keys, TouchPositionCorrection touchPositionCorrection, Map<Integer, List<Integer>> additionalProximityChars) { mGridWidth = gridWidth; mGridHeight = gridHeight; @@ -56,13 +57,15 @@ public class ProximityInfo { mCellHeight = (height + mGridHeight - 1) / mGridHeight; mKeyboardMinWidth = minWidth; mKeyboardHeight = height; - mKeyHeight = keyHeight; + mKeyHeight = mostCommonKeyHeight; + mMostCommonKeyWidth = mostCommonKeyWidth; mGridNeighbors = new Key[mGridSize][]; if (minWidth == 0 || height == 0) { // No proximity required. Keyboard might be more keys keyboard. return; } - computeNearestNeighbors(keyWidth, keys, touchPositionCorrection, additionalProximityChars); + computeNearestNeighbors( + mostCommonKeyWidth, keys, touchPositionCorrection, additionalProximityChars); } public static ProximityInfo createDummyProximityInfo() { @@ -74,8 +77,8 @@ public class ProximityInfo { final ProximityInfo spellCheckerProximityInfo = createDummyProximityInfo(); spellCheckerProximityInfo.mNativeProximityInfo = spellCheckerProximityInfo.setProximityInfoNative( - SpellCheckerProximityInfo.ROW_SIZE, 480, 300, 11, 3, proximity, 0, - null, null, null, null, null, null, null, null); + SpellCheckerProximityInfo.ROW_SIZE, 480, 300, 11, 3, (480 / 10), proximity, + 0, null, null, null, null, null, null, null, null); return spellCheckerProximityInfo; } @@ -85,7 +88,8 @@ public class ProximityInfo { } private native long setProximityInfoNative(int maxProximityCharsSize, int displayWidth, - int displayHeight, int gridWidth, int gridHeight, int[] proximityCharsArray, + int displayHeight, int gridWidth, int gridHeight, + int mostCommonKeyWidth, int[] proximityCharsArray, int keyCount, int[] keyXCoordinates, int[] keyYCoordinates, int[] keyWidths, int[] keyHeights, int[] keyCharCodes, float[] sweetSpotCenterX, float[] sweetSpotCenterY, float[] sweetSpotRadii); @@ -151,7 +155,8 @@ public class ProximityInfo { } mNativeProximityInfo = setProximityInfoNative(MAX_PROXIMITY_CHARS_SIZE, - keyboardWidth, keyboardHeight, mGridWidth, mGridHeight, proximityCharsArray, + keyboardWidth, keyboardHeight, mGridWidth, mGridHeight, mMostCommonKeyWidth, + proximityCharsArray, keyCount, keyXCoordinates, keyYCoordinates, keyWidths, keyHeights, keyCharCodes, sweetSpotCenterXs, sweetSpotCenterYs, sweetSpotRadii); } diff --git a/java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java b/java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java new file mode 100644 index 000000000..1cbdbd650 --- /dev/null +++ b/java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.latin; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.media.AudioManager; +import android.view.HapticFeedbackConstants; +import android.view.View; + +import com.android.inputmethod.compat.VibratorCompatWrapper; +import com.android.inputmethod.keyboard.Keyboard; + +/** + * This class gathers audio feedback and haptic feedback functions. + * + * It offers a consistent and simple interface that allows LatinIME to forget about the + * complexity of settings and the like. + */ +public class AudioAndHapticFeedbackManager extends BroadcastReceiver { + final private SettingsValues mSettingsValues; + final private AudioManager mAudioManager; + final private VibratorCompatWrapper mVibrator; + private boolean mSoundOn; + + public AudioAndHapticFeedbackManager(final LatinIME latinIme, + final SettingsValues settingsValues) { + mSettingsValues = settingsValues; + mVibrator = VibratorCompatWrapper.getInstance(latinIme); + mAudioManager = (AudioManager) latinIme.getSystemService(Context.AUDIO_SERVICE); + mSoundOn = reevaluateIfSoundIsOn(); + } + + public void hapticAndAudioFeedback(final int primaryCode, + final View viewToPerformHapticFeedbackOn) { + vibrate(viewToPerformHapticFeedbackOn); + playKeyClick(primaryCode); + } + + private boolean reevaluateIfSoundIsOn() { + if (!mSettingsValues.mSoundOn || mAudioManager == null) { + return false; + } else { + return mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_NORMAL; + } + } + + private void playKeyClick(int primaryCode) { + // if mAudioManager is null, we can't play a sound anyway, so return + if (mAudioManager == null) return; + if (mSoundOn) { + final int sound; + switch (primaryCode) { + case Keyboard.CODE_DELETE: + sound = AudioManager.FX_KEYPRESS_DELETE; + break; + case Keyboard.CODE_ENTER: + sound = AudioManager.FX_KEYPRESS_RETURN; + break; + case Keyboard.CODE_SPACE: + sound = AudioManager.FX_KEYPRESS_SPACEBAR; + break; + default: + sound = AudioManager.FX_KEYPRESS_STANDARD; + break; + } + mAudioManager.playSoundEffect(sound, mSettingsValues.mFxVolume); + } + } + + // TODO: make this private when LatinIME does not call it any more + public void vibrate(final View viewToPerformHapticFeedbackOn) { + if (!mSettingsValues.mVibrateOn) { + return; + } + if (mSettingsValues.mKeypressVibrationDuration < 0) { + // Go ahead with the system default + if (viewToPerformHapticFeedbackOn != null) { + viewToPerformHapticFeedbackOn.performHapticFeedback( + HapticFeedbackConstants.KEYBOARD_TAP, + HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); + } + } else if (mVibrator != null) { + mVibrator.vibrate(mSettingsValues.mKeypressVibrationDuration); + } + } + + @Override + public void onReceive(Context context, Intent intent) { + final String action = intent.getAction(); + // The following test is supposedly useless since we only listen for the ringer event. + // Still, it's a good safety measure. + if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) { + mSoundOn = reevaluateIfSoundIsOn(); + } + } +} diff --git a/java/src/com/android/inputmethod/latin/AutoCorrection.java b/java/src/com/android/inputmethod/latin/AutoCorrection.java index bcb78919d..a9489da54 100644 --- a/java/src/com/android/inputmethod/latin/AutoCorrection.java +++ b/java/src/com/android/inputmethod/latin/AutoCorrection.java @@ -25,18 +25,16 @@ import java.util.Map; public class AutoCorrection { private static final boolean DBG = LatinImeLogger.sDBG; private static final String TAG = AutoCorrection.class.getSimpleName(); - private boolean mHasAutoCorrection; private CharSequence mAutoCorrectionWord; private double mNormalizedScore; public void init() { - mHasAutoCorrection = false; mAutoCorrectionWord = null; mNormalizedScore = Integer.MIN_VALUE; } public boolean hasAutoCorrection() { - return mHasAutoCorrection; + return null != mAutoCorrectionWord; } public CharSequence getAutoCorrectionWord() { @@ -47,22 +45,20 @@ public class AutoCorrection { return mNormalizedScore; } - public void updateAutoCorrectionStatus(Map<String, Dictionary> dictionaries, + public CharSequence updateAutoCorrectionStatus(Map<String, Dictionary> dictionaries, WordComposer wordComposer, ArrayList<CharSequence> suggestions, int[] sortedScores, CharSequence typedWord, double autoCorrectionThreshold, int correctionMode, CharSequence whitelistedWord) { if (hasAutoCorrectionForWhitelistedWord(whitelistedWord)) { - mHasAutoCorrection = true; mAutoCorrectionWord = whitelistedWord; } else if (hasAutoCorrectionForTypedWord( dictionaries, wordComposer, suggestions, typedWord, correctionMode)) { - mHasAutoCorrection = true; mAutoCorrectionWord = typedWord; } else if (hasAutoCorrectionForBinaryDictionary(wordComposer, suggestions, correctionMode, sortedScores, typedWord, autoCorrectionThreshold)) { - mHasAutoCorrection = true; mAutoCorrectionWord = suggestions.get(0); } + return mAutoCorrectionWord; } public static boolean isValidWord( diff --git a/java/src/com/android/inputmethod/latin/ComposingStateManager.java b/java/src/com/android/inputmethod/latin/ComposingStateManager.java deleted file mode 100644 index 8811f2023..000000000 --- a/java/src/com/android/inputmethod/latin/ComposingStateManager.java +++ /dev/null @@ -1,68 +0,0 @@ -/** - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -package com.android.inputmethod.latin; - -import android.util.Log; - -public class ComposingStateManager { - private static final String TAG = ComposingStateManager.class.getSimpleName(); - private static final ComposingStateManager sInstance = new ComposingStateManager(); - private boolean mAutoCorrectionIndicatorOn; - private boolean mIsComposing; - - public static ComposingStateManager getInstance() { - return sInstance; - } - - private ComposingStateManager() { - mAutoCorrectionIndicatorOn = false; - mIsComposing = false; - } - - public synchronized void onStartComposingText() { - if (!mIsComposing) { - if (LatinImeLogger.sDBG) { - Log.i(TAG, "Start composing text."); - } - mAutoCorrectionIndicatorOn = false; - mIsComposing = true; - } - } - - public synchronized void onFinishComposingText() { - if (mIsComposing) { - if (LatinImeLogger.sDBG) { - Log.i(TAG, "Finish composing text."); - } - mAutoCorrectionIndicatorOn = false; - mIsComposing = false; - } - } - - public synchronized boolean isAutoCorrectionIndicatorOn() { - return mAutoCorrectionIndicatorOn; - } - - public synchronized void setAutoCorrectionIndicatorOn(boolean on) { - // Auto-correction indicator should be specified only when the current state is "composing". - if (!mIsComposing) return; - if (LatinImeLogger.sDBG) { - Log.i(TAG, "Set auto correction Indicator: " + on); - } - mAutoCorrectionIndicatorOn = on; - } -} diff --git a/java/src/com/android/inputmethod/latin/DebugSettings.java b/java/src/com/android/inputmethod/latin/DebugSettings.java index 3805da154..870b33f9a 100644 --- a/java/src/com/android/inputmethod/latin/DebugSettings.java +++ b/java/src/com/android/inputmethod/latin/DebugSettings.java @@ -25,6 +25,8 @@ import android.preference.CheckBoxPreference; import android.preference.PreferenceActivity; import android.util.Log; +import com.android.inputmethod.keyboard.KeyboardSwitcher; + public class DebugSettings extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener { @@ -61,7 +63,8 @@ public class DebugSettings extends PreferenceActivity updateDebugMode(); mServiceNeedsRestart = true; } - } else if (key.equals(FORCE_NON_DISTINCT_MULTITOUCH_KEY)) { + } else if (key.equals(FORCE_NON_DISTINCT_MULTITOUCH_KEY) + || key.equals(KeyboardSwitcher.PREF_KEYBOARD_LAYOUT)) { mServiceNeedsRestart = true; } } diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 1858db949..7a081c0c6 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -40,7 +40,6 @@ import android.text.TextUtils; import android.util.Log; import android.util.PrintWriterPrinter; import android.util.Printer; -import android.view.HapticFeedbackConstants; import android.view.KeyEvent; import android.view.View; import android.view.ViewGroup; @@ -61,7 +60,6 @@ import com.android.inputmethod.compat.InputMethodServiceCompatWrapper; import com.android.inputmethod.compat.InputMethodSubtypeCompatWrapper; import com.android.inputmethod.compat.InputTypeCompatUtils; import com.android.inputmethod.compat.SuggestionSpanUtils; -import com.android.inputmethod.compat.VibratorCompatWrapper; import com.android.inputmethod.deprecated.LanguageSwitcherProxy; import com.android.inputmethod.deprecated.VoiceProxy; import com.android.inputmethod.keyboard.Keyboard; @@ -223,10 +221,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar private int mDeleteCount; private long mLastKeyTime; - private AudioManager mAudioManager; - private boolean mSilentModeOn; // System-wide current configuration - - private VibratorCompatWrapper mVibrator; + private AudioAndHapticFeedbackManager mFeedbackManager; // Member variables for remembering the current device orientation. private int mDisplayOrientation; @@ -238,8 +233,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar // Keeps track of most recently inserted text (multi-character key) for reverting private CharSequence mEnteredText; - private final ComposingStateManager mComposingStateManager = - ComposingStateManager.getInstance(); + private boolean mIsAutoCorrectionIndicatorOn; public final UIHandler mHandler = new UIHandler(this); @@ -511,7 +505,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar super.onCreate(); mImm = InputMethodManagerCompatWrapper.getInstance(); - mVibrator = VibratorCompatWrapper.getInstance(this); mHandler.onCreate(); DEBUG = LatinImeLogger.sDBG; @@ -538,11 +531,14 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar // Register to receive ringer mode change and network state change. // Also receive installation and removal of a dictionary pack. final IntentFilter filter = new IntentFilter(); - filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION); filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); registerReceiver(mReceiver, filter); mVoiceProxy = VoiceProxy.init(this, prefs, mHandler); + final IntentFilter ringerModeFilter = new IntentFilter(); + ringerModeFilter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION); + registerReceiver(mFeedbackManager, ringerModeFilter); + final IntentFilter packageFilter = new IntentFilter(); packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED); packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); @@ -559,6 +555,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar /* package */ void loadSettings() { if (null == mPrefs) mPrefs = PreferenceManager.getDefaultSharedPreferences(this); mSettingsValues = new SettingsValues(mPrefs, this, mSubtypeSwitcher.getInputLocaleStr()); + mFeedbackManager = new AudioAndHapticFeedbackManager(this, mSettingsValues); resetContactsDictionary(null == mSuggest ? null : mSuggest.getContactsDictionary()); } @@ -647,6 +644,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar mSuggest = null; } unregisterReceiver(mReceiver); + unregisterReceiver(mFeedbackManager); unregisterReceiver(mDictionaryPackInstallReceiver); mVoiceProxy.destroy(); LatinImeLogger.commit(); @@ -657,7 +655,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar @Override public void onConfigurationChanged(Configuration conf) { mSubtypeSwitcher.onConfigurationChanged(conf); - mComposingStateManager.onFinishComposingText(); // If orientation changed while predicting, commit the change if (mDisplayOrientation != conf.orientation) { mDisplayOrientation = conf.orientation; @@ -1148,7 +1145,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar // and the composingStateManager about it. private void resetEntireInputState() { resetComposingState(true /* alsoResetLastComposedWord */); - mComposingStateManager.onFinishComposingText(); updateSuggestions(); final InputConnection ic = getCurrentInputConnection(); if (ic != null) { @@ -1339,6 +1335,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar // all inputs that do not result in a special state. Each character handling is then // free to override the state as they see fit. final int spaceState = mSpaceState; + if (!mWordComposer.isComposingWord()) mIsAutoCorrectionIndicatorOn = false; // TODO: Consolidate the double space timer, mLastKeyTime, and the space state. if (primaryCode != Keyboard.CODE_SPACE) { @@ -1588,7 +1585,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar // it entirely and resume suggestions on the previous word, we'd like to still // have touch coordinates for it. resetComposingState(false /* alsoResetLastComposedWord */); - mComposingStateManager.onFinishComposingText(); clearSuggestions(); } } @@ -1599,7 +1595,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar // If it's the first letter, make note of auto-caps state if (mWordComposer.size() == 1) { mWordComposer.setAutoCapitalized(getCurrentAutoCapsState()); - mComposingStateManager.onStartComposingText(); } ic.setComposingText(getTextWithUnderline(mWordComposer.getTypedWord()), 1); } @@ -1631,7 +1626,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar private boolean handleSeparator(final int primaryCode, final int x, final int y, final int spaceState) { mVoiceProxy.handleSeparator(); - mComposingStateManager.onFinishComposingText(); // Should dismiss the "Touch again to save" message when handling separator if (mSuggestionsView != null && mSuggestionsView.dismissAddToDictionaryHint()) { @@ -1711,7 +1705,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } private CharSequence getTextWithUnderline(final CharSequence text) { - return mComposingStateManager.isAutoCorrectionIndicatorOn() + return mIsAutoCorrectionIndicatorOn ? SuggestionSpanUtils.getTextWithAutoCorrectionIndicatorUnderline(this, text) : text; } @@ -1787,15 +1781,9 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar // Put a blue underline to a word in TextView which will be auto-corrected. final InputConnection ic = getCurrentInputConnection(); if (ic != null) { - final boolean oldAutoCorrectionIndicator = - mComposingStateManager.isAutoCorrectionIndicatorOn(); - if (oldAutoCorrectionIndicator != newAutoCorrectionIndicator) { - mComposingStateManager.setAutoCorrectionIndicatorOn(newAutoCorrectionIndicator); - if (DEBUG) { - Log.d(TAG, "Flip the indicator. " + oldAutoCorrectionIndicator - + " -> " + newAutoCorrectionIndicator); - } + if (mIsAutoCorrectionIndicatorOn != newAutoCorrectionIndicator) { if (mWordComposer.isComposingWord()) { + mIsAutoCorrectionIndicatorOn = newAutoCorrectionIndicator; final CharSequence textWithUnderline = getTextWithUnderline(mWordComposer.getTypedWord()); ic.setComposingText(textWithUnderline, 1); @@ -1941,7 +1929,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar @Override public void pickSuggestionManually(final int index, final CharSequence suggestion) { - mComposingStateManager.onFinishComposingText(); final SuggestedWords suggestedWords = mSuggestionsView.getSuggestions(); mVoiceProxy.flushAndLogAllTextModificationCounters(index, suggestion, mSettingsValues.mWordSeparators); @@ -2144,14 +2131,12 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar public boolean isCursorTouchingWord() { final InputConnection ic = getCurrentInputConnection(); if (ic == null) return false; - CharSequence toLeft = ic.getTextBeforeCursor(1, 0); - CharSequence toRight = ic.getTextAfterCursor(1, 0); - if (!TextUtils.isEmpty(toLeft) - && !mSettingsValues.isWordSeparator(toLeft.charAt(0))) { + CharSequence before = ic.getTextBeforeCursor(1, 0); + CharSequence after = ic.getTextAfterCursor(1, 0); + if (!TextUtils.isEmpty(before) && !mSettingsValues.isWordSeparator(before.charAt(0))) { return true; } - if (!TextUtils.isEmpty(toRight) - && !mSettingsValues.isWordSeparator(toRight.charAt(0))) { + if (!TextUtils.isEmpty(after) && !mSettingsValues.isWordSeparator(after.charAt(0))) { return true; } return false; @@ -2212,7 +2197,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar private void restartSuggestionsOnWordBeforeCursor(final InputConnection ic, final CharSequence word) { mWordComposer.setComposingWord(word, mKeyboardSwitcher.getKeyboard()); - mComposingStateManager.onStartComposingText(); ic.deleteSurroundingText(word.length(), 0); ic.setComposingText(word, 1); mHandler.postUpdateSuggestions(); @@ -2244,7 +2228,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar // This is the case when we cancel a manual pick. // We should restart suggestion on the word right away. mWordComposer.resumeSuggestionOnLastComposedWord(mLastComposedWord); - mComposingStateManager.onStartComposingText(); ic.setComposingText(originallyTypedWord, 1); } else { ic.commitText(originallyTypedWord, 1); @@ -2335,9 +2318,8 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } } - public void hapticAndAudioFeedback(int primaryCode) { - vibrate(); - playKeyClick(primaryCode); + public void hapticAndAudioFeedback(final int primaryCode) { + mFeedbackManager.hapticAndAudioFeedback(primaryCode, mKeyboardSwitcher.getKeyboardView()); } @Override @@ -2367,76 +2349,21 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar @Override public void onReceive(Context context, Intent intent) { final String action = intent.getAction(); - if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) { - updateRingerMode(); - } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) { + if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) { mSubtypeSwitcher.onNetworkStateChanged(intent); } } }; - // update flags for silent mode - private void updateRingerMode() { - if (mAudioManager == null) { - mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); - if (mAudioManager == null) return; - } - mSilentModeOn = (mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL); - } - - private void playKeyClick(int primaryCode) { - // if mAudioManager is null, we don't have the ringer state yet - // mAudioManager will be set by updateRingerMode - if (mAudioManager == null) { - if (mKeyboardSwitcher.getKeyboardView() != null) { - updateRingerMode(); - } - } - if (isSoundOn()) { - final int sound; - switch (primaryCode) { - case Keyboard.CODE_DELETE: - sound = AudioManager.FX_KEYPRESS_DELETE; - break; - case Keyboard.CODE_ENTER: - sound = AudioManager.FX_KEYPRESS_RETURN; - break; - case Keyboard.CODE_SPACE: - sound = AudioManager.FX_KEYPRESS_SPACEBAR; - break; - default: - sound = AudioManager.FX_KEYPRESS_STANDARD; - break; - } - mAudioManager.playSoundEffect(sound, mSettingsValues.mFxVolume); - } - } - + // TODO: remove this method when VoiceProxy has been removed public void vibrate() { - if (!mSettingsValues.mVibrateOn) { - return; - } - if (mSettingsValues.mKeypressVibrationDuration < 0) { - // Go ahead with the system default - LatinKeyboardView inputView = mKeyboardSwitcher.getKeyboardView(); - if (inputView != null) { - inputView.performHapticFeedback( - HapticFeedbackConstants.KEYBOARD_TAP, - HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); - } - } else if (mVibrator != null) { - mVibrator.vibrate(mSettingsValues.mKeypressVibrationDuration); - } + mFeedbackManager.vibrate(mKeyboardSwitcher.getKeyboardView()); } public boolean isAutoCapitalized() { return mWordComposer.isAutoCapitalized(); } - boolean isSoundOn() { - return mSettingsValues.mSoundOn && !mSilentModeOn; - } - private void updateCorrectionMode() { // TODO: cleanup messy flags final boolean shouldAutoCorrect = mSettingsValues.mAutoCorrectEnabled |