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 /**
     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 
     41     public static AudioAndHapticFeedbackManager getInstance() {
     42         return sInstance;
     43     }
     44 
     45     private AudioAndHapticFeedbackManager() {
     46         // Intentional empty constructor for singleton.
     47     }
     48 
     49     public static void init(final Context context) {
     50         sInstance.initInternal(context);
     51     }
     52 
     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 
     58     public void hapticAndAudioFeedback(final int primaryCode,
     59             final View viewToPerformHapticFeedbackOn) {
     60         vibrateInternal(viewToPerformHapticFeedbackOn);
     61         playKeyClick(primaryCode);
     62     }
     63 
     64     public boolean hasVibrator() {
     65         return mVibrator != null && mVibrator.hasVibrator();
     66     }
     67 
     68     public void vibrate(final long milliseconds) {
     69         if (mVibrator == null) {
     70             return;
     71         }
     72         mVibrator.vibrate(milliseconds);
     73     }
     74 
     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 
     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 
    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 
    123     public void onSettingsChanged(final SettingsValues settingsValues) {
    124         mSettingsValues = settingsValues;
    125         mSoundOn = reevaluateIfSoundIsOn();
    126     }
    127 
    128     public void onRingerModeChanged() {
    129         mSoundOn = reevaluateIfSoundIsOn();
    130     }
    131 }
    132