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..7455316df --- /dev/null +++ b/java/src/com/android/inputmethod/latin/AudioAndHapticFeedbackManager.java @@ -0,0 +1,124 @@ +/* + * 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 com.android.inputmethod.compat.VibratorCompatWrapper; +import com.android.inputmethod.keyboard.Keyboard; +import com.android.inputmethod.keyboard.KeyboardSwitcher; +import com.android.inputmethod.keyboard.LatinKeyboardView; + +/** + * 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 LatinIME mLatinIme; + final private SettingsValues mSettingsValues; + final private KeyboardSwitcher mKeyboardSwitcher; + private AudioManager mAudioManager; + final private VibratorCompatWrapper mVibrator; + private boolean mSilentModeOn; + + public AudioAndHapticFeedbackManager(final LatinIME latinIme, + final SettingsValues settingsValues, final KeyboardSwitcher keyboardSwitcher) { + mLatinIme = latinIme; + mSettingsValues = settingsValues; + mKeyboardSwitcher = keyboardSwitcher; + mSilentModeOn = true; + mVibrator = VibratorCompatWrapper.getInstance(mLatinIme); + } + + public void hapticAndAudioFeedback(final int primaryCode) { + vibrate(); + playKeyClick(primaryCode); + } + + private boolean isSoundOn() { + return mSettingsValues.mSoundOn && !mSilentModeOn; + } + + // update flags for silent mode + private void updateRingerMode() { + if (mAudioManager == null) { + mAudioManager = (AudioManager) mLatinIme.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: make this private when LatinIME does not call it any more + 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); + } + } + + @Override + public void onReceive(Context context, Intent intent) { + final String action = intent.getAction(); + if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) { + updateRingerMode(); + } + } +} diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index f8b339848..f8b5a677d 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -223,10 +223,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; @@ -510,7 +507,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar super.onCreate(); mImm = InputMethodManagerCompatWrapper.getInstance(); - mVibrator = VibratorCompatWrapper.getInstance(this); mHandler.onCreate(); DEBUG = LatinImeLogger.sDBG; @@ -537,11 +533,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); @@ -558,6 +557,8 @@ 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, + mKeyboardSwitcher); resetContactsDictionary(null == mSuggest ? null : mSuggest.getContactsDictionary()); } @@ -646,6 +647,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar mSuggest = null; } unregisterReceiver(mReceiver); + unregisterReceiver(mFeedbackManager); unregisterReceiver(mDictionaryPackInstallReceiver); mVoiceProxy.destroy(); LatinImeLogger.commit(); @@ -2321,9 +2323,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); } @Override @@ -2353,76 +2354,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(); } public boolean isAutoCapitalized() { return mWordComposer.isAutoCapitalized(); } - boolean isSoundOn() { - return mSettingsValues.mSoundOn && !mSilentModeOn; - } - private void updateCorrectionMode() { // TODO: cleanup messy flags final boolean shouldAutoCorrect = mSettingsValues.mAutoCorrectEnabled