| /* |
| * 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); |
| } |
| } |