diff options
author | Jake Hamby <jhamby@google.com> | 2012-08-27 12:37:17 -0700 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2012-08-27 12:37:17 -0700 |
commit | 7d7092565b7960e4f0823be387af9a89139f1136 (patch) | |
tree | 65dae25ba4463769f48b067ef6a75977d1e63746 /src | |
parent | c945c45175e820946c0ad5cb5f77e464828a85da (diff) | |
parent | bf70b6f871ac58439b5e98a305478a773e872b68 (diff) | |
download | android_packages_apps_CellBroadcastReceiver-7d7092565b7960e4f0823be387af9a89139f1136.tar.gz android_packages_apps_CellBroadcastReceiver-7d7092565b7960e4f0823be387af9a89139f1136.tar.bz2 android_packages_apps_CellBroadcastReceiver-7d7092565b7960e4f0823be387af9a89139f1136.zip |
am bf70b6f8: Fix behavior of CMAS audio alert and vibration.
* commit 'bf70b6f871ac58439b5e98a305478a773e872b68':
Fix behavior of CMAS audio alert and vibration.
Diffstat (limited to 'src')
4 files changed, 131 insertions, 47 deletions
diff --git a/src/com/android/cellbroadcastreceiver/CellBroadcastAlertAudio.java b/src/com/android/cellbroadcastreceiver/CellBroadcastAlertAudio.java index f817fc95..d4530723 100644 --- a/src/com/android/cellbroadcastreceiver/CellBroadcastAlertAudio.java +++ b/src/com/android/cellbroadcastreceiver/CellBroadcastAlertAudio.java @@ -61,11 +61,16 @@ public class CellBroadcastAlertAudio extends Service implements TextToSpeech.OnI public static final String ALERT_AUDIO_MESSAGE_LANGUAGE = "com.android.cellbroadcastreceiver.ALERT_AUDIO_MESSAGE_LANGUAGE"; + /** Extra for alert audio vibration enabled (from settings). */ + public static final String ALERT_AUDIO_VIBRATE_EXTRA = + "com.android.cellbroadcastreceiver.ALERT_AUDIO_VIBRATE"; + /** Pause duration between alert sound and alert speech. */ private static final int PAUSE_DURATION_BEFORE_SPEAKING_MSEC = 1000; /** Vibration uses the same on/off pattern as the CMAS alert tone */ - private static final long[] sVibratePattern = new long[] { 0, 2000, 500, 1000, 500, 1000, 500 }; + private static final long[] sVibratePattern = { 0, 2000, 500, 1000, 500, 1000, 500, + 2000, 500, 1000, 500, 1000}; /** CPU wake lock while playing audio. */ private PowerManager.WakeLock mWakeLock; @@ -83,6 +88,8 @@ public class CellBroadcastAlertAudio extends Service implements TextToSpeech.OnI private String mMessageBody; private String mMessageLanguage; private boolean mTtsLanguageSupported; + private boolean mEnableVibrate; + private boolean mEnableAudio; private Vibrator mVibrator; private MediaPlayer mMediaPlayer; @@ -204,13 +211,18 @@ public class CellBroadcastAlertAudio extends Service implements TextToSpeech.OnI @Override public void onDestroy() { + // stop audio, vibration and TTS stop(); // Stop listening for incoming calls. mTelephonyManager.listen(mPhoneStateListener, 0); // shutdown TTS engine if (mTts != null) { - mTts.stop(); - mTts.shutdown(); + try { + mTts.shutdown(); + } catch (IllegalStateException e) { + // catch "Unable to retrieve AudioTrack pointer for stop()" exception + Log.e(TAG, "exception trying to shutdown text-to-speech"); + } } // release CPU wake lock mWakeLock.release(); @@ -230,14 +242,34 @@ public class CellBroadcastAlertAudio extends Service implements TextToSpeech.OnI } // This extra should always be provided by CellBroadcastAlertService, - // but default to 4 seconds just to be safe - int duration = intent.getIntExtra(ALERT_AUDIO_DURATION_EXTRA, 4); + // but default to 10.5 seconds just to be safe (CMAS requirement). + int duration = intent.getIntExtra(ALERT_AUDIO_DURATION_EXTRA, 10500); // Get text to speak (if enabled by user) mMessageBody = intent.getStringExtra(ALERT_AUDIO_MESSAGE_BODY); mMessageLanguage = intent.getStringExtra(ALERT_AUDIO_MESSAGE_LANGUAGE); + mEnableVibrate = intent.getBooleanExtra(ALERT_AUDIO_VIBRATE_EXTRA, true); + + switch (mAudioManager.getRingerMode()) { + case AudioManager.RINGER_MODE_SILENT: + if (DBG) log("Ringer mode: silent"); + mEnableVibrate = false; + mEnableAudio = false; + break; + + case AudioManager.RINGER_MODE_VIBRATE: + if (DBG) log("Ringer mode: vibrate"); + mEnableAudio = false; + break; + + case AudioManager.RINGER_MODE_NORMAL: + default: + if (DBG) log("Ringer mode: normal"); + mEnableAudio = true; + break; + } - if (mMessageBody != null) { + if (mMessageBody != null && mEnableAudio) { if (mTts == null) { mTts = new TextToSpeech(this, this); } else if (mTtsEngineReady) { @@ -245,7 +277,12 @@ public class CellBroadcastAlertAudio extends Service implements TextToSpeech.OnI } } - play(duration * 1000); // convert to milliseconds + if (mEnableAudio || mEnableVibrate) { + play(duration); // in milliseconds + } else { + stopSelf(); + return START_NOT_STICKY; + } // Record the initial call state here so that the new alarm has the // newest state. @@ -267,38 +304,43 @@ public class CellBroadcastAlertAudio extends Service implements TextToSpeech.OnI if (DBG) log("play()"); - // future optimization: reuse media player object - mMediaPlayer = new MediaPlayer(); - mMediaPlayer.setOnErrorListener(new OnErrorListener() { - public boolean onError(MediaPlayer mp, int what, int extra) { - Log.e(TAG, "Error occurred while playing audio."); - mp.stop(); - mp.release(); - mMediaPlayer = null; - return true; - } - }); - - try { - // Check if we are in a call. If we are, play the alert - // sound at a low volume to not disrupt the call. - if (mTelephonyManager.getCallState() - != TelephonyManager.CALL_STATE_IDLE) { - Log.v(TAG, "in call: reducing volume"); - mMediaPlayer.setVolume(IN_CALL_VOLUME, IN_CALL_VOLUME); - } - // start playing alert audio - setDataSourceFromResource(getResources(), mMediaPlayer, - R.raw.attention_signal); - mAudioManager.requestAudioFocus(null, AudioManager.STREAM_ALARM, - AudioManager.AUDIOFOCUS_GAIN_TRANSIENT); - startAlarm(mMediaPlayer); - } catch (Exception ex) { - Log.e(TAG, "Failed to play alert sound", ex); + // Start the vibration first. + if (mEnableVibrate) { + mVibrator.vibrate(sVibratePattern, -1); } - /* Start the vibrator after everything is ok with the media player */ - mVibrator.vibrate(sVibratePattern, 1); + if (mEnableAudio) { + // future optimization: reuse media player object + mMediaPlayer = new MediaPlayer(); + mMediaPlayer.setOnErrorListener(new OnErrorListener() { + public boolean onError(MediaPlayer mp, int what, int extra) { + Log.e(TAG, "Error occurred while playing audio."); + mp.stop(); + mp.release(); + mMediaPlayer = null; + return true; + } + }); + + try { + // Check if we are in a call. If we are, play the alert + // sound at a low volume to not disrupt the call. + if (mTelephonyManager.getCallState() + != TelephonyManager.CALL_STATE_IDLE) { + Log.v(TAG, "in call: reducing volume"); + mMediaPlayer.setVolume(IN_CALL_VOLUME, IN_CALL_VOLUME); + } + + // start playing alert audio (unless master volume is vibrate only or silent). + setDataSourceFromResource(getResources(), mMediaPlayer, + R.raw.attention_signal); + mAudioManager.requestAudioFocus(null, AudioManager.STREAM_NOTIFICATION, + AudioManager.AUDIOFOCUS_GAIN_TRANSIENT); + startAlarm(mMediaPlayer); + } catch (Exception ex) { + Log.e(TAG, "Failed to play alert sound", ex); + } + } // stop alert after the specified duration mHandler.sendMessageDelayed(mHandler.obtainMessage(ALERT_SOUND_FINISHED), duration); @@ -307,9 +349,8 @@ public class CellBroadcastAlertAudio extends Service implements TextToSpeech.OnI // Do the common stuff when starting the alarm. private static void startAlarm(MediaPlayer player) - throws java.io.IOException, IllegalArgumentException, - IllegalStateException { - player.setAudioStreamType(AudioManager.STREAM_ALARM); + throws java.io.IOException, IllegalArgumentException, IllegalStateException { + player.setAudioStreamType(AudioManager.STREAM_NOTIFICATION); player.setLooping(true); player.prepare(); player.start(); @@ -337,15 +378,25 @@ public class CellBroadcastAlertAudio extends Service implements TextToSpeech.OnI if (mState == STATE_ALERTING) { // Stop audio playing if (mMediaPlayer != null) { - mMediaPlayer.stop(); - mMediaPlayer.release(); + try { + mMediaPlayer.stop(); + mMediaPlayer.release(); + } catch (IllegalStateException e) { + // catch "Unable to retrieve AudioTrack pointer for stop()" exception + Log.e(TAG, "exception trying to stop media player"); + } mMediaPlayer = null; } // Stop vibrator mVibrator.cancel(); } else if (mState == STATE_SPEAKING && mTts != null) { - mTts.stop(); + try { + mTts.stop(); + } catch (IllegalStateException e) { + // catch "Unable to retrieve AudioTrack pointer for stop()" exception + Log.e(TAG, "exception trying to stop text-to-speech"); + } } mAudioManager.abandonAudioFocus(null); mState = STATE_IDLE; diff --git a/src/com/android/cellbroadcastreceiver/CellBroadcastAlertFullScreen.java b/src/com/android/cellbroadcastreceiver/CellBroadcastAlertFullScreen.java index a8337f30..5bc2ba54 100644 --- a/src/com/android/cellbroadcastreceiver/CellBroadcastAlertFullScreen.java +++ b/src/com/android/cellbroadcastreceiver/CellBroadcastAlertFullScreen.java @@ -26,6 +26,7 @@ import android.os.Handler; import android.os.Message; import android.provider.Telephony; import android.telephony.CellBroadcastMessage; +import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.Window; @@ -200,6 +201,25 @@ public class CellBroadcastAlertFullScreen extends Activity { finish(); } + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + switch (event.getKeyCode()) { + // Volume keys and camera keys mute the alert sound/vibration. + case KeyEvent.KEYCODE_VOLUME_UP: + case KeyEvent.KEYCODE_VOLUME_DOWN: + case KeyEvent.KEYCODE_VOLUME_MUTE: + case KeyEvent.KEYCODE_CAMERA: + case KeyEvent.KEYCODE_FOCUS: + // Stop playing alert sound/vibration/speech (if started) + stopService(new Intent(this, CellBroadcastAlertAudio.class)); + return true; + + default: + break; + } + return super.dispatchKeyEvent(event); + } + /** * Ignore the back button for emergency alerts (overridden by alert dialog so that the dialog * is dismissed). diff --git a/src/com/android/cellbroadcastreceiver/CellBroadcastAlertService.java b/src/com/android/cellbroadcastreceiver/CellBroadcastAlertService.java index dc1021fb..08b21544 100644 --- a/src/com/android/cellbroadcastreceiver/CellBroadcastAlertService.java +++ b/src/com/android/cellbroadcastreceiver/CellBroadcastAlertService.java @@ -261,10 +261,20 @@ public class CellBroadcastAlertService extends Service { Intent audioIntent = new Intent(this, CellBroadcastAlertAudio.class); audioIntent.setAction(CellBroadcastAlertAudio.ACTION_START_ALERT_AUDIO); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); - String duration = prefs.getString(CellBroadcastSettings.KEY_ALERT_SOUND_DURATION, - CellBroadcastSettings.ALERT_SOUND_DEFAULT_DURATION); - audioIntent.putExtra(CellBroadcastAlertAudio.ALERT_AUDIO_DURATION_EXTRA, - Integer.parseInt(duration)); + + int duration; // alert audio duration in ms + if (message.isCmasMessage()) { + // CMAS requirement: duration of the audio attention signal is 10.5 seconds. + duration = 10500; + } else { + duration = Integer.parseInt(prefs.getString( + CellBroadcastSettings.KEY_ALERT_SOUND_DURATION, + CellBroadcastSettings.ALERT_SOUND_DEFAULT_DURATION)) * 1000; + } + audioIntent.putExtra(CellBroadcastAlertAudio.ALERT_AUDIO_DURATION_EXTRA, duration); + + audioIntent.putExtra(CellBroadcastAlertAudio.ALERT_AUDIO_VIBRATE_EXTRA, + prefs.getBoolean(CellBroadcastSettings.KEY_ENABLE_ALERT_VIBRATE, true)); int channelTitleId = CellBroadcastResources.getDialogTitleResource(message); CharSequence channelName = getText(channelTitleId); diff --git a/src/com/android/cellbroadcastreceiver/CellBroadcastSettings.java b/src/com/android/cellbroadcastreceiver/CellBroadcastSettings.java index 973cb312..cd372a44 100644 --- a/src/com/android/cellbroadcastreceiver/CellBroadcastSettings.java +++ b/src/com/android/cellbroadcastreceiver/CellBroadcastSettings.java @@ -40,6 +40,9 @@ public class CellBroadcastSettings extends PreferenceActivity { // Default alert duration (in seconds). public static final String ALERT_SOUND_DEFAULT_DURATION = "4"; + // Enable vibration on alert (unless master volume is silent). + public static final String KEY_ENABLE_ALERT_VIBRATE = "enable_alert_vibrate"; + // Speak contents of alert after playing the alert sound. public static final String KEY_ENABLE_ALERT_SPEECH = "enable_alert_speech"; |