From 4c85c1d6f4e97f33e03a8f28f882d7a4110b8f88 Mon Sep 17 00:00:00 2001 From: Przemyslaw Szczepaniak Date: Fri, 2 Aug 2013 17:06:41 +0100 Subject: [PATCH] Disable TTS "Listen to the example" if not supported If current TTS locale (most of the cases same as device locale) is not supported by the TTS engine, field for setting synthesis speed and "Listen to the example" will be disabled. Added new field, "Default language status" to indicate level of support for currently selected language. It can take one of three messages: %s is fully supported %s requires network connection %s is not supported Where %s is locale display name. Added example string that will provide a fallback for example text if not provided by Settings or TTS engine. Change-Id: Ia2a920a71197a85d3812fc8df9dfed4ebe6b515f Bug: 9982002 --- res/values/strings.xml | 15 ++ res/xml/tts_settings.xml | 5 + .../settings/tts/TextToSpeechSettings.java | 142 ++++++++++++------ 3 files changed, 116 insertions(+), 46 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index b7973408e58..49a888bea4e 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -3560,6 +3560,21 @@ This language requires a working network connection for text-to-speech output. + + This is an example of speech synthesis + + Default language status + + %1$s is fully supported + + %1$s requires network connection + + %1$s is not supported Engines diff --git a/res/xml/tts_settings.xml b/res/xml/tts_settings.xml index 2b145d18828..ab132df9e3d 100644 --- a/res/xml/tts_settings.xml +++ b/res/xml/tts_settings.xml @@ -37,4 +37,9 @@ android:persistent="false" android:title="@string/tts_play_example_title" android:summary="@string/tts_play_example_summary" /> + + diff --git a/src/com/android/settings/tts/TextToSpeechSettings.java b/src/com/android/settings/tts/TextToSpeechSettings.java index 8f83bbc77b6..10ac575971b 100644 --- a/src/com/android/settings/tts/TextToSpeechSettings.java +++ b/src/com/android/settings/tts/TextToSpeechSettings.java @@ -60,6 +60,9 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements /** Preference key for the TTS rate selection dialog. */ private static final String KEY_DEFAULT_RATE = "tts_default_rate"; + /** Preference key for the TTS status field. */ + private static final String KEY_STATUS = "tts_status"; + /** * Preference key for the engine selection preference. */ @@ -75,6 +78,7 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements private PreferenceCategory mEnginePreferenceCategory; private ListPreference mDefaultRatePref; private Preference mPlayExample; + private Preference mEngineStatus; private int mDefaultRate = TextToSpeech.Engine.DEFAULT_RATE; @@ -98,6 +102,9 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements private TextToSpeech mTts = null; private TtsEngines mEnginesHelper = null; + private String mSampleText = ""; + private Locale mCurrentDefaultLocale; + /** * The initialization listener used when we are initalizing the settings * screen for the first time (as opposed to when a user changes his choice @@ -136,6 +143,8 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements KEY_ENGINE_PREFERENCE_SECTION); mDefaultRatePref = (ListPreference) findPreference(KEY_DEFAULT_RATE); + mEngineStatus = findPreference(KEY_STATUS); + mTts = new TextToSpeech(getActivity().getApplicationContext(), mInitListener); mEnginesHelper = new TtsEngines(getActivity().getApplicationContext()); @@ -143,6 +152,20 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements initSettings(); } + @Override + public void onResume() { + super.onResume(); + + if (mTts == null || mCurrentDefaultLocale == null) { + return; + } + Locale ttsDefaultLocale = mTts.getDefaultLanguage(); + if (mCurrentDefaultLocale != null && !mCurrentDefaultLocale.equals(ttsDefaultLocale)) { + updateWidgetState(false); + checkDefaultLocale(); + } + } + private void setTtsUtteranceProgressListener() { if (mTts == null) { return; @@ -205,6 +228,46 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements checkVoiceData(mCurrentEngine); } + /** + * Called when the TTS engine is initialized. + */ + public void onInitEngine(int status) { + if (status == TextToSpeech.SUCCESS) { + if (DBG) Log.d(TAG, "TTS engine for settings screen initialized."); + checkDefaultLocale(); + } else { + if (DBG) Log.d(TAG, "TTS engine for settings screen failed to initialize successfully."); + updateWidgetState(false); + } + } + + private void checkDefaultLocale() { + Locale defaultLocale = mTts.getDefaultLanguage(); + if (defaultLocale == null) { + Log.e(TAG, "Failed to get default language from engine " + mCurrentEngine); + updateWidgetState(false); + updateEngineStatus(R.string.tts_status_not_supported); + return; + } + + mCurrentDefaultLocale = defaultLocale; + + int defaultAvailable = mTts.setLanguage(defaultLocale); + if (defaultAvailable == TextToSpeech.LANG_NOT_SUPPORTED) { + if (DBG) Log.d(TAG, "Default locale for this TTS engine is not supported."); + updateWidgetState(false); + updateEngineStatus(R.string.tts_status_not_supported); + } else { + if (isNetworkRequiredForSynthesis()) { + updateEngineStatus(R.string.tts_status_requires_network); + } else { + updateEngineStatus(R.string.tts_status_ok); + } + getSampleText(); + } + } + + /** * Ask the current default engine to return a string of sample text to be * spoken to the user. @@ -214,23 +277,15 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements if (TextUtils.isEmpty(currentEngine)) currentEngine = mTts.getDefaultEngine(); - - Locale defaultLocale = mTts.getDefaultLanguage(); - if (defaultLocale == null) { - Log.e(TAG, "Failed to get default language from engine " + currentEngine); - return; - } - mTts.setLanguage(defaultLocale); - // TODO: This is currently a hidden private API. The intent extras // and the intent action should be made public if we intend to make this // a public API. We fall back to using a canned set of strings if this // doesn't work. Intent intent = new Intent(TextToSpeech.Engine.ACTION_GET_SAMPLE_TEXT); - intent.putExtra("language", defaultLocale.getLanguage()); - intent.putExtra("country", defaultLocale.getCountry()); - intent.putExtra("variant", defaultLocale.getVariant()); + intent.putExtra("language", mCurrentDefaultLocale.getLanguage()); + intent.putExtra("country", mCurrentDefaultLocale.getCountry()); + intent.putExtra("variant", mCurrentDefaultLocale.getVariant()); intent.setPackage(currentEngine); try { @@ -241,19 +296,6 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements } } - /** - * Called when the TTS engine is initialized. - */ - public void onInitEngine(int status) { - if (status == TextToSpeech.SUCCESS) { - updateWidgetState(true); - if (DBG) Log.d(TAG, "TTS engine for settings screen initialized."); - } else { - if (DBG) Log.d(TAG, "TTS engine for settings screen failed to initialize successfully."); - updateWidgetState(false); - } - } - /** * Called when voice data integrity check returns */ @@ -280,11 +322,11 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements } } } - return null; + return getString(R.string.tts_default_sample_string); } private boolean isNetworkRequiredForSynthesis() { - Set features = mTts.getFeatures(mTts.getLanguage()); + Set features = mTts.getFeatures(mCurrentDefaultLocale); return features.contains(TextToSpeech.Engine.KEY_FEATURE_NETWORK_SYNTHESIS) && !features.contains(TextToSpeech.Engine.KEY_FEATURE_EMBEDDED_SYNTHESIS); } @@ -301,24 +343,25 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements if (DBG) Log.d(TAG, "Using default sample text :" + sample); } - if (sample != null && mTts != null) { - // The engine is guaranteed to have been initialized here - // because this preference is not enabled otherwise. - - final boolean networkRequired = isNetworkRequiredForSynthesis(); - if (!networkRequired || networkRequired && - (mTts.isLanguageAvailable(mTts.getLanguage()) >= TextToSpeech.LANG_AVAILABLE)) { - HashMap params = new HashMap(); - params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "Sample"); - - mTts.speak(sample, TextToSpeech.QUEUE_FLUSH, params); - } else { - Log.w(TAG, "Network required for sample synthesis for requested language"); - displayNetworkAlert(); - } + mSampleText = sample; + if (mSampleText != null) { + updateWidgetState(true); } else { - // TODO: Display an error here to the user. - Log.e(TAG, "Did not have a sample string for the requested language"); + Log.e(TAG, "Did not have a sample string for the requested language. Using default"); + } + } + + private void speakSampleText() { + final boolean networkRequired = isNetworkRequiredForSynthesis(); + if (!networkRequired || networkRequired && + (mTts.isLanguageAvailable(mCurrentDefaultLocale) >= TextToSpeech.LANG_AVAILABLE)) { + HashMap params = new HashMap(); + params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "Sample"); + + mTts.speak(mSampleText, TextToSpeech.QUEUE_FLUSH, params); + } else { + Log.w(TAG, "Network required for sample synthesis for requested language"); + displayNetworkAlert(); } } @@ -349,7 +392,7 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements if (preference == mPlayExample) { // Get the sample text from the TTS engine; onActivityResult will do // the actual speaking - getSampleText(); + speakSampleText(); return true; } @@ -359,6 +402,15 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements private void updateWidgetState(boolean enable) { mPlayExample.setEnabled(enable); mDefaultRatePref.setEnabled(enable); + mEngineStatus.setEnabled(enable); + } + + private void updateEngineStatus(int resourceId) { + Locale locale = mCurrentDefaultLocale; + if (locale == null) { + locale = Locale.getDefault(); + } + mEngineStatus.setSummary(getString(resourceId, locale.getDisplayName())); } private void displayNetworkAlert() { @@ -474,8 +526,6 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements } } } - - updateWidgetState(true); } @Override