AudioAndHapticFeedbackManager.java revision 2651b17fc4fb4457deb5078114b26d3a1ec66799
1564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard/*
2564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard * Copyright (C) 2012 The Android Open Source Project
3564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard *
4564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard * use this file except in compliance with the License. You may obtain a copy of
6564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard * the License at
7564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard *
8564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard * http://www.apache.org/licenses/LICENSE-2.0
9564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard *
10564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard * Unless required by applicable law or agreed to in writing, software
11564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard * License for the specific language governing permissions and limitations under
14564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard * the License.
15564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard */
16564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard
17564496bad6207f02e7a653872213bc5954e84ce4Jean Chalardpackage com.android.inputmethod.latin;
18564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard
19564496bad6207f02e7a653872213bc5954e84ce4Jean Chalardimport android.content.BroadcastReceiver;
20564496bad6207f02e7a653872213bc5954e84ce4Jean Chalardimport android.content.Context;
21564496bad6207f02e7a653872213bc5954e84ce4Jean Chalardimport android.content.Intent;
22564496bad6207f02e7a653872213bc5954e84ce4Jean Chalardimport android.media.AudioManager;
23564496bad6207f02e7a653872213bc5954e84ce4Jean Chalardimport android.view.HapticFeedbackConstants;
24564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard
25564496bad6207f02e7a653872213bc5954e84ce4Jean Chalardimport com.android.inputmethod.compat.VibratorCompatWrapper;
26564496bad6207f02e7a653872213bc5954e84ce4Jean Chalardimport com.android.inputmethod.keyboard.Keyboard;
27564496bad6207f02e7a653872213bc5954e84ce4Jean Chalardimport com.android.inputmethod.keyboard.KeyboardSwitcher;
28564496bad6207f02e7a653872213bc5954e84ce4Jean Chalardimport com.android.inputmethod.keyboard.LatinKeyboardView;
29564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard
30564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard/**
31564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard * This class gathers audio feedback and haptic feedback functions.
32564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard *
33564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard * It offers a consistent and simple interface that allows LatinIME to forget about the
34564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard * complexity of settings and the like.
35564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard */
36564496bad6207f02e7a653872213bc5954e84ce4Jean Chalardpublic class AudioAndHapticFeedbackManager extends BroadcastReceiver {
37564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard    final private LatinIME mLatinIme;
38564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard    final private SettingsValues mSettingsValues;
39564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard    final private KeyboardSwitcher mKeyboardSwitcher;
40793791cdf0d54a55a73f931ffe3c62590c881f1eJean Chalard    final private AudioManager mAudioManager;
41564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard    final private VibratorCompatWrapper mVibrator;
422651b17fc4fb4457deb5078114b26d3a1ec66799Jean Chalard    private boolean mSoundOn;
43564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard
44564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard    public AudioAndHapticFeedbackManager(final LatinIME latinIme,
45564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard            final SettingsValues settingsValues, final KeyboardSwitcher keyboardSwitcher) {
46564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard        mLatinIme = latinIme;
47564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard        mSettingsValues = settingsValues;
48564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard        mKeyboardSwitcher = keyboardSwitcher;
492651b17fc4fb4457deb5078114b26d3a1ec66799Jean Chalard        mSoundOn = false;
50564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard        mVibrator = VibratorCompatWrapper.getInstance(mLatinIme);
51793791cdf0d54a55a73f931ffe3c62590c881f1eJean Chalard        mAudioManager = (AudioManager) mLatinIme.getSystemService(Context.AUDIO_SERVICE);
52793791cdf0d54a55a73f931ffe3c62590c881f1eJean Chalard        updateRingerMode();
53564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard    }
54564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard
55564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard    public void hapticAndAudioFeedback(final int primaryCode) {
56564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard        vibrate();
57564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard        playKeyClick(primaryCode);
58564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard    }
59564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard
60564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard    private boolean isSoundOn() {
612651b17fc4fb4457deb5078114b26d3a1ec66799Jean Chalard        return mSettingsValues.mSoundOn && mSoundOn;
62564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard    }
63564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard
64564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard    // update flags for silent mode
65564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard    private void updateRingerMode() {
66793791cdf0d54a55a73f931ffe3c62590c881f1eJean Chalard        if (!mSettingsValues.mSoundOn || mAudioManager == null) {
672651b17fc4fb4457deb5078114b26d3a1ec66799Jean Chalard            mSoundOn = false;
68793791cdf0d54a55a73f931ffe3c62590c881f1eJean Chalard        } else {
692651b17fc4fb4457deb5078114b26d3a1ec66799Jean Chalard            mSoundOn = (mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_NORMAL);
70564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard        }
71564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard    }
72564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard
73564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard    private void playKeyClick(int primaryCode) {
74793791cdf0d54a55a73f931ffe3c62590c881f1eJean Chalard        // if mAudioManager is null, we can't play a sound anyway, so return
75793791cdf0d54a55a73f931ffe3c62590c881f1eJean Chalard        if (mAudioManager == null) return;
76564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard        if (isSoundOn()) {
77564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard            final int sound;
78564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard            switch (primaryCode) {
79564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard            case Keyboard.CODE_DELETE:
80564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard                sound = AudioManager.FX_KEYPRESS_DELETE;
81564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard                break;
82564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard            case Keyboard.CODE_ENTER:
83564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard                sound = AudioManager.FX_KEYPRESS_RETURN;
84564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard                break;
85564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard            case Keyboard.CODE_SPACE:
86564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard                sound = AudioManager.FX_KEYPRESS_SPACEBAR;
87564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard                break;
88564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard            default:
89564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard                sound = AudioManager.FX_KEYPRESS_STANDARD;
90564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard                break;
91564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard            }
92564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard            mAudioManager.playSoundEffect(sound, mSettingsValues.mFxVolume);
93564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard        }
94564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard    }
95564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard
96564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard    // TODO: make this private when LatinIME does not call it any more
97564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard    public void vibrate() {
98564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard        if (!mSettingsValues.mVibrateOn) {
99564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard            return;
100564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard        }
101564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard        if (mSettingsValues.mKeypressVibrationDuration < 0) {
102564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard            // Go ahead with the system default
103564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard            LatinKeyboardView inputView = mKeyboardSwitcher.getKeyboardView();
104564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard            if (inputView != null) {
105564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard                inputView.performHapticFeedback(
106564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard                        HapticFeedbackConstants.KEYBOARD_TAP,
107564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard                        HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
108564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard            }
109564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard        } else if (mVibrator != null) {
110564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard            mVibrator.vibrate(mSettingsValues.mKeypressVibrationDuration);
111564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard        }
112564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard    }
113564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard
114564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard    @Override
115564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard    public void onReceive(Context context, Intent intent) {
116564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard        final String action = intent.getAction();
117564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard        if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {
118564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard            updateRingerMode();
119564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard        }
120564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard    }
121564496bad6207f02e7a653872213bc5954e84ce4Jean Chalard}
122