Merge changes I3447b591,Ic54a8307
* changes:
Fixed that emergency alert text-to-speech does not work
Fixed that emergency alert does not vibrate in DnD mode
diff --git a/res/raw-zh-rTW b/res/raw-zh-rTW
new file mode 120000
index 0000000..cef6542
--- /dev/null
+++ b/res/raw-zh-rTW
@@ -0,0 +1 @@
+raw-zh
\ No newline at end of file
diff --git a/src/com/android/cellbroadcastreceiver/CellBroadcastAlertAudio.java b/src/com/android/cellbroadcastreceiver/CellBroadcastAlertAudio.java
index bb869f5..abb3235 100644
--- a/src/com/android/cellbroadcastreceiver/CellBroadcastAlertAudio.java
+++ b/src/com/android/cellbroadcastreceiver/CellBroadcastAlertAudio.java
@@ -17,11 +17,11 @@
package com.android.cellbroadcastreceiver;
import static com.android.cellbroadcastreceiver.CellBroadcastReceiver.DBG;
-import static com.android.cellbroadcastreceiver.CellBroadcastReceiver.VDBG;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.content.res.AssetFileDescriptor;
import android.content.res.Resources;
import android.media.AudioAttributes;
@@ -30,22 +30,22 @@
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
-import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
+import android.os.VibrationEffect;
import android.os.Vibrator;
import android.preference.PreferenceManager;
import android.provider.Settings;
import android.speech.tts.TextToSpeech;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
+import android.text.TextUtils;
import android.util.Log;
import com.android.cellbroadcastreceiver.CellBroadcastAlertService.AlertType;
import java.util.Locale;
-import java.util.MissingResourceException;
/**
* Manages alert audio and vibration and text-to-speech. Runs as a service so that
@@ -63,22 +63,13 @@
"com.android.cellbroadcastreceiver.ALERT_AUDIO_MESSAGE_BODY";
/** Extra for text-to-speech preferred language (if speech enabled in settings). */
- public static final String ALERT_AUDIO_MESSAGE_PREFERRED_LANGUAGE =
- "com.android.cellbroadcastreceiver.ALERT_AUDIO_MESSAGE_PREFERRED_LANGUAGE";
-
- /** Extra for text-to-speech default language when preferred language is
- not available (if speech enabled in settings). */
- public static final String ALERT_AUDIO_MESSAGE_DEFAULT_LANGUAGE =
- "com.android.cellbroadcastreceiver.ALERT_AUDIO_MESSAGE_DEFAULT_LANGUAGE";
+ public static final String ALERT_AUDIO_MESSAGE_LANGUAGE =
+ "com.android.cellbroadcastreceiver.ALERT_AUDIO_MESSAGE_LANGUAGE";
/** Extra for alert tone type */
public static final String ALERT_AUDIO_TONE_TYPE =
"com.android.cellbroadcastreceiver.ALERT_AUDIO_TONE_TYPE";
- /** Extra for alert audio vibration enabled (from settings). */
- public static final String ALERT_AUDIO_VIBRATE_EXTRA =
- "com.android.cellbroadcastreceiver.ALERT_AUDIO_VIBRATE";
-
/** Extra for alert vibration pattern (unless master volume is silent). */
public static final String ALERT_AUDIO_VIBRATION_PATTERN_EXTRA =
"com.android.cellbroadcastreceiver.ALERT_VIBRATION_PATTERN";
@@ -99,8 +90,7 @@
private boolean mTtsEngineReady;
private String mMessageBody;
- private String mMessagePreferredLanguage;
- private String mMessageDefaultLanguage;
+ private String mMessageLanguage;
private boolean mTtsLanguageSupported;
private boolean mEnableVibrate;
private boolean mEnableAudio;
@@ -147,16 +137,8 @@
if (mMessageBody != null && mTtsEngineReady && mTtsLanguageSupported) {
if (DBG) log("Speaking broadcast text: " + mMessageBody);
- Bundle params = new Bundle();
- // Play TTS in the alarm stream, which we use for playing alert tones as
- // well.
- params.putInt(TextToSpeech.Engine.KEY_PARAM_STREAM,
- AudioManager.STREAM_ALARM);
- // Use the non-public parameter 2 --> TextToSpeech.QUEUE_DESTROY for TTS.
- // The entire playback queue is purged. This is different from QUEUE_FLUSH
- // in that all entries are purged, not just entries from a given caller.
- // This is for emergency so we want to kill all other TTS sessions.
- res = mTts.speak(mMessageBody, 2, params, TTS_UTTERANCE_ID);
+ mTts.setAudioAttributes(getAlertAudioAttributes());
+ res = mTts.speak(mMessageBody, 2, null, TTS_UTTERANCE_ID);
mState = STATE_SPEAKING;
}
if (res != TextToSpeech.SUCCESS) {
@@ -189,7 +171,7 @@
*/
@Override
public void onInit(int status) {
- if (VDBG) log("onInit() TTS engine status: " + status);
+ if (DBG) log("onInit() TTS engine status: " + status);
if (status == TextToSpeech.SUCCESS) {
mTtsEngineReady = true;
mTts.setOnUtteranceCompletedListener(this);
@@ -207,31 +189,20 @@
* it to the default language. mTtsLanguageSupported will be updated based on the response.
*/
private void setTtsLanguage() {
-
- String language = mMessagePreferredLanguage;
- if (language == null || language.isEmpty() ||
- TextToSpeech.LANG_AVAILABLE != mTts.isLanguageAvailable(new Locale(language))) {
- language = mMessageDefaultLanguage;
- if (language == null || language.isEmpty() ||
- TextToSpeech.LANG_AVAILABLE != mTts.isLanguageAvailable(new Locale(language))) {
- mTtsLanguageSupported = false;
- return;
- }
- if (DBG) log("Language '" + mMessagePreferredLanguage + "' is not available, using" +
- "the default language '" + mMessageDefaultLanguage + "'");
+ Locale locale;
+ if (!TextUtils.isEmpty(mMessageLanguage)) {
+ locale = new Locale(mMessageLanguage);
+ } else {
+ // If the cell broadcast message does not specify the language, use device's default
+ // language.
+ locale = Locale.getDefault();
}
- if (DBG) log("Setting TTS language to '" + language + '\'');
+ if (DBG) log("Setting TTS language to '" + locale + '\'');
- try {
- int result = mTts.setLanguage(new Locale(language));
- if (DBG) log("TTS setLanguage() returned: " + result);
- mTtsLanguageSupported = (result == TextToSpeech.LANG_AVAILABLE);
- }
- catch (MissingResourceException e) {
- mTtsLanguageSupported = false;
- loge("Language '" + language + "' is not available.");
- }
+ int result = mTts.setLanguage(locale);
+ if (DBG) log("TTS setLanguage() returned: " + result);
+ mTtsLanguageSupported = (result >= TextToSpeech.LANG_AVAILABLE);
}
/**
@@ -300,27 +271,33 @@
// Get text to speak (if enabled by user)
mMessageBody = intent.getStringExtra(ALERT_AUDIO_MESSAGE_BODY);
- mMessagePreferredLanguage = intent.getStringExtra(ALERT_AUDIO_MESSAGE_PREFERRED_LANGUAGE);
- mMessageDefaultLanguage = intent.getStringExtra(ALERT_AUDIO_MESSAGE_DEFAULT_LANGUAGE);
+ mMessageLanguage = intent.getStringExtra(ALERT_AUDIO_MESSAGE_LANGUAGE);
+
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
// Get config of whether to always sound CBS alerts at full volume.
- mUseFullVolume = PreferenceManager.getDefaultSharedPreferences(this)
- .getBoolean(CellBroadcastSettings.KEY_USE_FULL_VOLUME, false);
+ mUseFullVolume = prefs.getBoolean(CellBroadcastSettings.KEY_USE_FULL_VOLUME, false);
// retrieve the vibrate settings from cellbroadcast receiver settings.
- mEnableVibrate = intent.getBooleanExtra(ALERT_AUDIO_VIBRATE_EXTRA, true);
+ mEnableVibrate = prefs.getBoolean(CellBroadcastSettings.KEY_ENABLE_ALERT_VIBRATE, true);
// retrieve the vibration patterns
mVibrationPattern = intent.getIntArrayExtra(ALERT_AUDIO_VIBRATION_PATTERN_EXTRA);
switch (mAudioManager.getRingerMode()) {
case AudioManager.RINGER_MODE_SILENT:
if (DBG) log("Ringer mode: silent");
- mEnableAudio = false;
- mEnableVibrate = false;
+ if (!mUseFullVolume) {
+ mEnableVibrate = false;
+ }
+ // If the phone is in silent mode, we only enable the audio when use full volume
+ // setting is turned on.
+ mEnableAudio = mUseFullVolume;
break;
case AudioManager.RINGER_MODE_VIBRATE:
if (DBG) log("Ringer mode: vibrate");
- mEnableAudio = false;
+ // If the phone is in vibration mode, we only enable the audio when use full volume
+ // setting is turned on.
+ mEnableAudio = mUseFullVolume;
break;
case AudioManager.RINGER_MODE_NORMAL:
default:
@@ -329,10 +306,6 @@
break;
}
- if (mUseFullVolume) {
- mEnableAudio = true;
- }
-
if (mMessageBody != null && mEnableAudio) {
if (mTts == null) {
mTts = new TextToSpeech(this, this);
@@ -386,7 +359,15 @@
vibrationPattern[i] = patternArray[i];
vibrateDuration += patternArray[i];
}
- mVibrator.vibrate(vibrationPattern, 0);
+
+ // Use the alarm channel so it can vibrate in DnD mode, unless alarms are
+ // specifically disabled in DnD.
+ AudioAttributes.Builder attrBuilder = new AudioAttributes.Builder();
+ attrBuilder.setUsage(AudioAttributes.USAGE_ALARM);
+ AudioAttributes attr = attrBuilder.build();
+ VibrationEffect effect = VibrationEffect.createWaveform(vibrationPattern, 0);
+ log("vibrate: effect=" + effect + ", attr=" + attr);
+ mVibrator.vibrate(effect, attr);
}
@@ -455,9 +436,7 @@
// Request audio focus (though we're going to play even if we don't get it)
mAudioManager.requestAudioFocus(null, AudioManager.STREAM_ALARM,
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
- mMediaPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
-
- setAlertAudioAttributes();
+ mMediaPlayer.setAudioAttributes(getAlertAudioAttributes());
setAlertVolume();
// If we are using the custom alert duration, set looping to true so we can repeat
@@ -533,10 +512,9 @@
}
/**
- * Set AudioAttributes for mMediaPlayer. Replacement of deprecated
- * mMediaPlayer.setAudioStreamType.
+ * Get audio attribute for the alarm.
*/
- private void setAlertAudioAttributes() {
+ private AudioAttributes getAlertAudioAttributes() {
AudioAttributes.Builder builder = new AudioAttributes.Builder();
builder.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION);
@@ -548,7 +526,7 @@
| AudioAttributes.FLAG_BYPASS_MUTE);
}
- mMediaPlayer.setAudioAttributes(builder.build());
+ return builder.build();
}
/**
diff --git a/src/com/android/cellbroadcastreceiver/CellBroadcastAlertService.java b/src/com/android/cellbroadcastreceiver/CellBroadcastAlertService.java
index b969f62..c779043 100644
--- a/src/com/android/cellbroadcastreceiver/CellBroadcastAlertService.java
+++ b/src/com/android/cellbroadcastreceiver/CellBroadcastAlertService.java
@@ -578,8 +578,6 @@
CellBroadcastChannelRange range = CellBroadcastChannelManager
.getCellBroadcastChannelRangeFromMessage(getApplicationContext(), message);
audioIntent.putExtra(CellBroadcastAlertAudio.ALERT_AUDIO_TONE_TYPE, alertType);
- audioIntent.putExtra(CellBroadcastAlertAudio.ALERT_AUDIO_VIBRATE_EXTRA,
- prefs.getBoolean(CellBroadcastSettings.KEY_ENABLE_ALERT_VIBRATE, true));
audioIntent.putExtra(CellBroadcastAlertAudio.ALERT_AUDIO_VIBRATION_PATTERN_EXTRA,
(range != null) ? range.mVibrationPattern
: getApplicationContext().getResources().getIntArray(
@@ -590,34 +588,11 @@
if (prefs.getBoolean(CellBroadcastSettings.KEY_ENABLE_ALERT_SPEECH, true)) {
audioIntent.putExtra(CellBroadcastAlertAudio.ALERT_AUDIO_MESSAGE_BODY, messageBody);
- String preferredLanguage = message.getLanguageCode();
- String defaultLanguage = null;
- if (message.isEtwsMessage()) {
- // Only do TTS for ETWS secondary message.
- // There is no text in ETWS primary message. When we construct the ETWS primary
- // message, we hardcode "ETWS" as the body hence we don't want to speak that out
- // here.
+ String language = message.getLanguageCode();
- // Also in many cases we see the secondary message comes few milliseconds after
- // the primary one. If we play TTS for the primary one, It will be overwritten by
- // the secondary one immediately anyway.
- if (!message.getEtwsWarningInfo().isPrimary()) {
- // Since only Japanese carriers are using ETWS, if there is no language
- // specified in the ETWS message, we'll use Japanese as the default language.
- defaultLanguage = "ja";
- }
- } else {
- // If there is no language specified in the CMAS message, use device's
- // default language.
- defaultLanguage = Locale.getDefault().getLanguage();
- }
-
- Log.d(TAG, "Preferred language = " + preferredLanguage +
- ", Default language = " + defaultLanguage);
- audioIntent.putExtra(CellBroadcastAlertAudio.ALERT_AUDIO_MESSAGE_PREFERRED_LANGUAGE,
- preferredLanguage);
- audioIntent.putExtra(CellBroadcastAlertAudio.ALERT_AUDIO_MESSAGE_DEFAULT_LANGUAGE,
- defaultLanguage);
+ Log.d(TAG, "Message language = " + language);
+ audioIntent.putExtra(CellBroadcastAlertAudio.ALERT_AUDIO_MESSAGE_LANGUAGE,
+ language);
}
startService(audioIntent);