• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.inputmethod.latin;
18 
19 import android.content.Context;
20 import android.media.AudioManager;
21 import android.os.Vibrator;
22 import android.view.HapticFeedbackConstants;
23 import android.view.View;
24 
25 /**
26  * This class gathers audio feedback and haptic feedback functions.
27  *
28  * It offers a consistent and simple interface that allows LatinIME to forget about the
29  * complexity of settings and the like.
30  */
31 public final class AudioAndHapticFeedbackManager {
32     private AudioManager mAudioManager;
33     private Vibrator mVibrator;
34 
35     private SettingsValues mSettingsValues;
36     private boolean mSoundOn;
37 
38     private static final AudioAndHapticFeedbackManager sInstance =
39             new AudioAndHapticFeedbackManager();
40 
getInstance()41     public static AudioAndHapticFeedbackManager getInstance() {
42         return sInstance;
43     }
44 
AudioAndHapticFeedbackManager()45     private AudioAndHapticFeedbackManager() {
46         // Intentional empty constructor for singleton.
47     }
48 
init(final Context context)49     public static void init(final Context context) {
50         sInstance.initInternal(context);
51     }
52 
initInternal(final Context context)53     private void initInternal(final Context context) {
54         mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
55         mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
56     }
57 
hapticAndAudioFeedback(final int primaryCode, final View viewToPerformHapticFeedbackOn)58     public void hapticAndAudioFeedback(final int primaryCode,
59             final View viewToPerformHapticFeedbackOn) {
60         vibrateInternal(viewToPerformHapticFeedbackOn);
61         playKeyClick(primaryCode);
62     }
63 
hasVibrator()64     public boolean hasVibrator() {
65         return mVibrator != null && mVibrator.hasVibrator();
66     }
67 
vibrate(final long milliseconds)68     public void vibrate(final long milliseconds) {
69         if (mVibrator == null) {
70             return;
71         }
72         mVibrator.vibrate(milliseconds);
73     }
74 
reevaluateIfSoundIsOn()75     private boolean reevaluateIfSoundIsOn() {
76         if (mSettingsValues == null || !mSettingsValues.mSoundOn || mAudioManager == null) {
77             return false;
78         }
79         return mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_NORMAL;
80     }
81 
playKeyClick(final int primaryCode)82     private void playKeyClick(final int primaryCode) {
83         // if mAudioManager is null, we can't play a sound anyway, so return
84         if (mAudioManager == null) {
85             return;
86         }
87         if (mSoundOn) {
88             final int sound;
89             switch (primaryCode) {
90             case Constants.CODE_DELETE:
91                 sound = AudioManager.FX_KEYPRESS_DELETE;
92                 break;
93             case Constants.CODE_ENTER:
94                 sound = AudioManager.FX_KEYPRESS_RETURN;
95                 break;
96             case Constants.CODE_SPACE:
97                 sound = AudioManager.FX_KEYPRESS_SPACEBAR;
98                 break;
99             default:
100                 sound = AudioManager.FX_KEYPRESS_STANDARD;
101                 break;
102             }
103             mAudioManager.playSoundEffect(sound, mSettingsValues.mKeypressSoundVolume);
104         }
105     }
106 
vibrateInternal(final View viewToPerformHapticFeedbackOn)107     private void vibrateInternal(final View viewToPerformHapticFeedbackOn) {
108         if (!mSettingsValues.mVibrateOn) {
109             return;
110         }
111         if (mSettingsValues.mKeypressVibrationDuration < 0) {
112             // Go ahead with the system default
113             if (viewToPerformHapticFeedbackOn != null) {
114                 viewToPerformHapticFeedbackOn.performHapticFeedback(
115                         HapticFeedbackConstants.KEYBOARD_TAP,
116                         HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
117             }
118             return;
119         }
120         vibrate(mSettingsValues.mKeypressVibrationDuration);
121     }
122 
onSettingsChanged(final SettingsValues settingsValues)123     public void onSettingsChanged(final SettingsValues settingsValues) {
124         mSettingsValues = settingsValues;
125         mSoundOn = reevaluateIfSoundIsOn();
126     }
127 
onRingerModeChanged()128     public void onRingerModeChanged() {
129         mSoundOn = reevaluateIfSoundIsOn();
130     }
131 }
132