1 /* 2 * Copyright (C) 2014 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.services.telephony; 18 19 import android.content.Context; 20 import android.media.AudioAttributes; 21 import android.media.AudioManager; 22 import android.media.ToneGenerator; 23 import android.os.SystemVibrator; 24 import android.os.Vibrator; 25 import android.provider.Settings; 26 27 /** 28 * Plays an emergency tone when placing emergency calls on CDMA devices. 29 */ 30 class EmergencyTonePlayer { 31 32 private static final int EMERGENCY_TONE_OFF = 0; 33 private static final int EMERGENCY_TONE_ALERT = 1; 34 private static final int EMERGENCY_TONE_VIBRATE = 2; 35 36 private static final int ALERT_RELATIVE_VOLUME_PERCENT = 100; 37 38 private static final int VIBRATE_LENGTH_MILLIS = 1000; 39 private static final int VIBRATE_PAUSE_MILLIS = 1000; 40 private static final long[] VIBRATE_PATTERN = 41 new long[] { VIBRATE_LENGTH_MILLIS, VIBRATE_PAUSE_MILLIS}; 42 43 private static final AudioAttributes VIBRATION_ATTRIBUTES = 44 new AudioAttributes.Builder() 45 .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH) 46 .setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION) 47 .build(); 48 49 // We don't rely on getSystemService(Context.VIBRATOR_SERVICE) to make sure that this vibrator 50 // object will be isolated from others. 51 private final Vibrator mVibrator = new SystemVibrator(); 52 private final Context mContext; 53 private final AudioManager mAudioManager; 54 55 private ToneGenerator mToneGenerator; 56 private int mSavedInCallVolume; 57 private boolean mIsVibrating = false; 58 59 EmergencyTonePlayer(Context context) { 60 mContext = context; 61 mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); 62 } 63 64 public void start() { 65 switch (getToneSetting()) { 66 case EMERGENCY_TONE_VIBRATE: 67 startVibrate(); 68 break; 69 case EMERGENCY_TONE_ALERT: 70 // Only start if we are not in silent mode. 71 int ringerMode = mAudioManager.getRingerMode(); 72 if (ringerMode == AudioManager.RINGER_MODE_NORMAL) { 73 startAlert(); 74 } 75 break; 76 case EMERGENCY_TONE_OFF: 77 // nothing; 78 break; 79 } 80 } 81 82 public void stop() { 83 stopVibrate(); 84 stopAlert(); 85 } 86 87 private void startVibrate() { 88 if (!mIsVibrating) { 89 mVibrator.vibrate(VIBRATE_PATTERN, 0, VIBRATION_ATTRIBUTES); 90 mIsVibrating = true; 91 } 92 } 93 94 private void stopVibrate() { 95 if (mIsVibrating) { 96 mVibrator.cancel(); 97 mIsVibrating = false; 98 } 99 } 100 101 private void startAlert() { 102 if (mToneGenerator == null) { 103 mToneGenerator = new ToneGenerator( 104 AudioManager.STREAM_VOICE_CALL, ALERT_RELATIVE_VOLUME_PERCENT); 105 106 // Set the volume to max and save the old volume setting. 107 mSavedInCallVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL); 108 mAudioManager.setStreamVolume( 109 AudioManager.STREAM_VOICE_CALL, 110 mAudioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL), 111 0); 112 mToneGenerator.startTone(ToneGenerator.TONE_CDMA_EMERGENCY_RINGBACK); 113 } else { 114 Log.d(this, "An alert is already running."); 115 } 116 } 117 118 private void stopAlert() { 119 if (mToneGenerator != null) { 120 mToneGenerator.stopTone(); 121 mToneGenerator.release(); 122 mToneGenerator = null; 123 124 mAudioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL, mSavedInCallVolume, 0); 125 mSavedInCallVolume = 0; 126 } 127 } 128 129 private int getToneSetting() { 130 return Settings.Global.getInt( 131 mContext.getContentResolver(), Settings.Global.EMERGENCY_TONE, EMERGENCY_TONE_OFF); 132 } 133 } 134