blob: aaec24fc4db849c115f82d55dda74d95114c774b [file] [log] [blame]
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.services.telephony;
import android.content.Context;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.ToneGenerator;
import android.os.SystemVibrator;
import android.os.Vibrator;
import android.provider.Settings;
/**
* Plays an emergency tone when placing emergency calls on CDMA devices.
*/
class EmergencyTonePlayer {
private static final int EMERGENCY_TONE_OFF = 0;
private static final int EMERGENCY_TONE_ALERT = 1;
private static final int EMERGENCY_TONE_VIBRATE = 2;
private static final int ALERT_RELATIVE_VOLUME_PERCENT = 100;
private static final int VIBRATE_LENGTH_MILLIS = 1000;
private static final int VIBRATE_PAUSE_MILLIS = 1000;
private static final long[] VIBRATE_PATTERN =
new long[] { VIBRATE_LENGTH_MILLIS, VIBRATE_PAUSE_MILLIS};
private static final AudioAttributes VIBRATION_ATTRIBUTES =
new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
.setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
.build();
// We don't rely on getSystemService(Context.VIBRATOR_SERVICE) to make sure that this vibrator
// object will be isolated from others.
private final Vibrator mVibrator = new SystemVibrator();
private final Context mContext;
private final AudioManager mAudioManager;
private ToneGenerator mToneGenerator;
private int mSavedInCallVolume;
private boolean mIsVibrating = false;
EmergencyTonePlayer(Context context) {
mContext = context;
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
}
public void start() {
switch (getToneSetting()) {
case EMERGENCY_TONE_VIBRATE:
startVibrate();
break;
case EMERGENCY_TONE_ALERT:
// Only start if we are not in silent mode.
int ringerMode = mAudioManager.getRingerMode();
if (ringerMode == AudioManager.RINGER_MODE_NORMAL) {
startAlert();
}
break;
case EMERGENCY_TONE_OFF:
// nothing;
break;
}
}
public void stop() {
stopVibrate();
stopAlert();
}
private void startVibrate() {
if (!mIsVibrating) {
mVibrator.vibrate(VIBRATE_PATTERN, 0, VIBRATION_ATTRIBUTES);
mIsVibrating = true;
}
}
private void stopVibrate() {
if (mIsVibrating) {
mVibrator.cancel();
mIsVibrating = false;
}
}
private void startAlert() {
if (mToneGenerator == null) {
mToneGenerator = new ToneGenerator(
AudioManager.STREAM_VOICE_CALL, ALERT_RELATIVE_VOLUME_PERCENT);
// Set the volume to max and save the old volume setting.
mSavedInCallVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL);
mAudioManager.setStreamVolume(
AudioManager.STREAM_VOICE_CALL,
mAudioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL),
0);
mToneGenerator.startTone(ToneGenerator.TONE_CDMA_EMERGENCY_RINGBACK);
} else {
Log.d(this, "An alert is already running.");
}
}
private void stopAlert() {
if (mToneGenerator != null) {
mToneGenerator.stopTone();
mToneGenerator.release();
mToneGenerator = null;
mAudioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL, mSavedInCallVolume, 0);
mSavedInCallVolume = 0;
}
}
private int getToneSetting() {
return Settings.Global.getInt(
mContext.getContentResolver(), Settings.Global.EMERGENCY_TONE, EMERGENCY_TONE_OFF);
}
}