Home | History | Annotate | Download | only in latin
      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 import com.android.inputmethod.latin.common.Constants;
     26 import com.android.inputmethod.latin.settings.SettingsValues;
     27 
     28 /**
     29  * This class gathers audio feedback and haptic feedback functions.
     30  *
     31  * It offers a consistent and simple interface that allows LatinIME to forget about the
     32  * complexity of settings and the like.
     33  */
     34 public final class AudioAndHapticFeedbackManager {
     35     private AudioManager mAudioManager;
     36     private Vibrator mVibrator;
     37 
     38     private SettingsValues mSettingsValues;
     39     private boolean mSoundOn;
     40 
     41     private static final AudioAndHapticFeedbackManager sInstance =
     42             new AudioAndHapticFeedbackManager();
     43 
     44     public static AudioAndHapticFeedbackManager getInstance() {
     45         return sInstance;
     46     }
     47 
     48     private AudioAndHapticFeedbackManager() {
     49         // Intentional empty constructor for singleton.
     50     }
     51 
     52     public static void init(final Context context) {
     53         sInstance.initInternal(context);
     54     }
     55 
     56     private void initInternal(final Context context) {
     57         mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
     58         mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
     59     }
     60 
     61     public void performHapticAndAudioFeedback(final int code,
     62             final View viewToPerformHapticFeedbackOn) {
     63         performHapticFeedback(viewToPerformHapticFeedbackOn);
     64         performAudioFeedback(code);
     65     }
     66 
     67     public boolean hasVibrator() {
     68         return mVibrator != null && mVibrator.hasVibrator();
     69     }
     70 
     71     public void vibrate(final long milliseconds) {
     72         if (mVibrator == null) {
     73             return;
     74         }
     75         mVibrator.vibrate(milliseconds);
     76     }
     77 
     78     private boolean reevaluateIfSoundIsOn() {
     79         if (mSettingsValues == null || !mSettingsValues.mSoundOn || mAudioManager == null) {
     80             return false;
     81         }
     82         return mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_NORMAL;
     83     }
     84 
     85     public void performAudioFeedback(final int code) {
     86         // if mAudioManager is null, we can't play a sound anyway, so return
     87         if (mAudioManager == null) {
     88             return;
     89         }
     90         if (!mSoundOn) {
     91             return;
     92         }
     93         final int sound;
     94         switch (code) {
     95         case Constants.CODE_DELETE:
     96             sound = AudioManager.FX_KEYPRESS_DELETE;
     97             break;
     98         case Constants.CODE_ENTER:
     99             sound = AudioManager.FX_KEYPRESS_RETURN;
    100             break;
    101         case Constants.CODE_SPACE:
    102             sound = AudioManager.FX_KEYPRESS_SPACEBAR;
    103             break;
    104         default:
    105             sound = AudioManager.FX_KEYPRESS_STANDARD;
    106             break;
    107         }
    108         mAudioManager.playSoundEffect(sound, mSettingsValues.mKeypressSoundVolume);
    109     }
    110 
    111     public void performHapticFeedback(final View viewToPerformHapticFeedbackOn) {
    112         if (!mSettingsValues.mVibrateOn) {
    113             return;
    114         }
    115         if (mSettingsValues.mKeypressVibrationDuration >= 0) {
    116             vibrate(mSettingsValues.mKeypressVibrationDuration);
    117             return;
    118         }
    119         // Go ahead with the system default
    120         if (viewToPerformHapticFeedbackOn != null) {
    121             viewToPerformHapticFeedbackOn.performHapticFeedback(
    122                     HapticFeedbackConstants.KEYBOARD_TAP,
    123                     HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
    124         }
    125     }
    126 
    127     public void onSettingsChanged(final SettingsValues settingsValues) {
    128         mSettingsValues = settingsValues;
    129         mSoundOn = reevaluateIfSoundIsOn();
    130     }
    131 
    132     public void onRingerModeChanged() {
    133         mSoundOn = reevaluateIfSoundIsOn();
    134     }
    135 }
    136