From d5642f7060ffe8b5c2f1f760d99f4fcf487b0276 Mon Sep 17 00:00:00 2001 From: Narayan Kamath Date: Tue, 14 Jun 2011 18:17:40 +0100 Subject: [PATCH] Text to speech settings UI change. No more separate checkboxes for each of the engines. This brings it more in line with the voice recognition settings. The user is shown a data warning every time he chooses a non system engine as the default. Change-Id: I00fcb9c9f634a9fc13ff14da8bfade79ae6727c4 --- res/values/strings.xml | 8 + res/xml/tts_settings.xml | 39 ++- .../settings/TextToSpeechSettings.java | 239 ++++++++---------- 3 files changed, 136 insertions(+), 150 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 1cc955c340e..c1ca934803c 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -2878,6 +2878,14 @@ found in the list of installed applications. %s is enabled %s is disabled + + Engine settings + + Settings for %s Languages and voices diff --git a/res/xml/tts_settings.xml b/res/xml/tts_settings.xml index c378f64b253..ecccc1031c5 100644 --- a/res/xml/tts_settings.xml +++ b/res/xml/tts_settings.xml @@ -4,9 +4,9 @@ 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. @@ -18,17 +18,11 @@ android:title="@string/tts_settings_title"> + android:key="tts_play_example" + android:persistent="false" + android:title="@string/tts_play_example_title" + android:summary="@string/tts_play_example_summary" /> - - - - - + + + + + diff --git a/src/com/android/settings/TextToSpeechSettings.java b/src/com/android/settings/TextToSpeechSettings.java index 34ce2515a66..1f81c9905f8 100644 --- a/src/com/android/settings/TextToSpeechSettings.java +++ b/src/com/android/settings/TextToSpeechSettings.java @@ -21,7 +21,6 @@ import static android.provider.Settings.Secure.TTS_DEFAULT_LANG; import static android.provider.Settings.Secure.TTS_DEFAULT_RATE; import static android.provider.Settings.Secure.TTS_DEFAULT_SYNTH; import static android.provider.Settings.Secure.TTS_DEFAULT_VARIANT; -import static android.provider.Settings.Secure.TTS_ENABLED_PLUGINS; import static android.provider.Settings.Secure.TTS_USE_DEFAULTS; import android.app.AlertDialog; @@ -32,7 +31,6 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Bundle; -import android.preference.CheckBoxPreference; import android.preference.ListPreference; import android.preference.Preference; import android.preference.Preference.OnPreferenceClickListener; @@ -64,7 +62,7 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements private static final String KEY_TTS_DEFAULT_COUNTRY = "tts_default_country"; private static final String KEY_TTS_DEFAULT_VARIANT = "tts_default_variant"; private static final String KEY_TTS_DEFAULT_SYNTH = "tts_default_synth"; - private static final String KEY_TTS_ENGINES = "tts_engines_section"; + private static final String KEY_TTS_ENGINE_SETTINGS = "tts_engine_settings"; private static final String KEY_PLUGIN_ENABLED_PREFIX = "ENABLED_"; private static final String KEY_PLUGIN_SETTINGS_PREFIX = "SETTINGS_"; @@ -76,13 +74,14 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements private static final String LOCALE_DELIMITER = "-"; - private Preference mPlayExample = null; - private Preference mInstallData = null; - private CheckBoxPreference mUseDefaultPref = null; - private ListPreference mDefaultRatePref = null; - private ListPreference mDefaultLocPref = null; - private ListPreference mDefaultSynthPref = null; - private PreferenceGroup mEnginesGroup; + private Preference mPlayExample = null; + + private ListPreference mDefaultRatePref = null; + private ListPreference mDefaultLocPref = null; + private ListPreference mDefaultSynthPref = null; + + private Preference mInstallData = null; + private Preference mEngineSettings = null; private String mDefaultLanguage = null; private String mDefaultCountry = null; @@ -127,18 +126,18 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements mInstallData = findPreference(KEY_TTS_INSTALL_DATA); mInstallData.setOnPreferenceClickListener(this); - mUseDefaultPref = (CheckBoxPreference) findPreference(KEY_TTS_USE_DEFAULT); mDefaultSynthPref = (ListPreference) findPreference(KEY_TTS_DEFAULT_SYNTH); mDefaultRatePref = (ListPreference) findPreference(KEY_TTS_DEFAULT_RATE); mDefaultLocPref = (ListPreference) findPreference(KEY_TTS_DEFAULT_LANG); - mEnginesGroup = (PreferenceGroup) findPreference(KEY_TTS_ENGINES); + mEngineSettings = (Preference) findPreference(KEY_TTS_ENGINE_SETTINGS); + mEngineSettings.setEnabled(false); mTts = new TextToSpeech(getActivity().getApplicationContext(), this); mEnginesHelper = new TtsEngines(getActivity().getApplicationContext()); initDefaultSettings(); - addEngineSpecificSettings(); + initEngineSpecificSettings(); } @Override @@ -175,39 +174,27 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements } } - private void addEngineSpecificSettings() { - Context context = getActivity(); - List engines = mTts.getEngines(); - for (EngineInfo engine : engines) { - final String engineName = engine.name; - if (!engine.system) { - CheckBoxPreference enablePref = new CheckBoxPreference(context); - enablePref.setKey(KEY_PLUGIN_ENABLED_PREFIX + engineName); - enablePref.setTitle(engine.label); - enablePref.setOnPreferenceClickListener(this); - mEnginesGroup.addPreference(enablePref); - } + private void initEngineSpecificSettings() { + final String engineName = mEnginesHelper.getDefaultEngine(); + final EngineInfo engine = mEnginesHelper.getEngineInfo(engineName); - if (engineHasSettings(engineName)) { - Preference pref = new Preference(context); - pref.setKey(KEY_PLUGIN_SETTINGS_PREFIX + engineName); - pref.setTitle(engine.label); - CharSequence settingsLabel = getResources().getString( - R.string.tts_engine_name_settings, engine.label); - pref.setSummary(settingsLabel); - // TODO: Add a new API for this. - pref.setOnPreferenceClickListener(new OnPreferenceClickListener() { - public boolean onPreferenceClick(Preference preference) { - Intent i = new Intent(); - i.setClassName(engineName, - engineName + ".EngineSettings"); - startActivity(i); - return true; - } - }); - mEnginesGroup.addPreference(pref); - } + mEngineSettings.setTitle(getResources().getString(R.string.tts_engine_settings_title, + engine.label)); + + if (engineHasSettings(engineName)) { + mEngineSettings.setOnPreferenceClickListener(new OnPreferenceClickListener() { + public boolean onPreferenceClick(Preference preference) { + Intent i = new Intent(); + i.setClassName(engineName, engineName + ".EngineSettings"); + startActivity(i); + return true; + } + }); + mEngineSettings.setEnabled(true); + } else { + mEngineSettings.setEnabled(false); } + } private boolean engineHasSettings(String enginePackageName) { @@ -226,12 +213,6 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements // Find the default TTS values in the settings, initialize and store the // settings if they are not found. - // "Use Defaults" - int useDefault = Settings.Secure.getInt(resolver, TTS_USE_DEFAULTS, - TextToSpeech.Engine.USE_DEFAULTS); - mUseDefaultPref.setChecked(useDefault == 1); - mUseDefaultPref.setOnPreferenceChangeListener(this); - // Default synthesis engine loadEngines(); mDefaultSynthPref.setOnPreferenceChangeListener(this); @@ -301,6 +282,7 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements intent.putExtra("country", mDefaultCountry); intent.putExtra("variant", mDefaultLocVariant); intent.setPackage(defaultEngine); + try { Log.v(TAG, "Getting sample text: " + intent.toUri(0)); startActivityForResult(intent, GET_SAMPLE_TEXT); @@ -504,16 +486,21 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements Log.v(TAG, " selected is " + newIndex); mDemoStringIndex = newIndex > -1 ? newIndex : 0; } else if (KEY_TTS_DEFAULT_SYNTH.equals(preference.getKey())) { - String defaultEng = objValue.toString(); - Settings.Secure.putString(getContentResolver(), TTS_DEFAULT_SYNTH, defaultEng); - if (mTts != null) { - mTts.setEngineByPackageName(defaultEng); - mEnableDemo = false; - mVoicesMissing = false; - updateWidgetState(); - checkVoiceData(); + final String name = objValue.toString(); + final EngineInfo info = mEnginesHelper.getEngineInfo(name); + + if (info.system) { + // For system engines, do away with the alert dialog. + updateDefaultEngine(name); + initEngineSpecificSettings(); + } else { + // For all other engines, display a warning message before + // turning them on. + displayDataAlert(preference, name); } - Log.v(TAG, "The default synth is: " + objValue.toString()); + + // We'll deal with updating the UI ourselves. + return false; } return true; @@ -534,42 +521,13 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements // quit this activity so it needs to be restarted after installation of the voice data finish(); return true; - } else if (preference.getKey().startsWith(KEY_PLUGIN_ENABLED_PREFIX)) { - final CheckBoxPreference chkPref = (CheckBoxPreference) preference; - if (chkPref.isChecked()) { - chkPref.setChecked(false); - AlertDialog d = (new AlertDialog.Builder(getActivity())) - .setTitle(android.R.string.dialog_alert_title) - .setIcon(android.R.drawable.ic_dialog_alert) - .setMessage( - getActivity().getString(R.string.tts_engine_security_warning, - chkPref.getTitle())) - .setCancelable(true) - .setPositiveButton(android.R.string.ok, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - chkPref.setChecked(true); - loadEngines(); - } - }) - .setNegativeButton(android.R.string.cancel, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - } - }) - .create(); - d.show(); - } else { - loadEngines(); - } - return true; } + return false; } private void updateWidgetState() { mPlayExample.setEnabled(mEnableDemo); - mUseDefaultPref.setEnabled(mEnableDemo); mDefaultRatePref.setEnabled(mEnableDemo); mDefaultLocPref.setEnabled(mEnableDemo); @@ -582,14 +540,18 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements mDefaultLanguage = ""; mDefaultCountry = ""; mDefaultLocVariant = ""; - if (tokenizer.hasMoreTokens()) { - mDefaultLanguage = tokenizer.nextToken().trim(); - } - if (tokenizer.hasMoreTokens()) { - mDefaultCountry = tokenizer.nextToken().trim(); - } - if (tokenizer.hasMoreTokens()) { - mDefaultLocVariant = tokenizer.nextToken().trim(); + + if (locale != null) { + String[] components = locale.split(LOCALE_DELIMITER); + if (components.length > 0) { + mDefaultLanguage = components[0]; + } + if (components.length > 1) { + mDefaultCountry = components[1]; + } + if (components.length > 2) { + mDefaultLocVariant = components[2]; + } } } @@ -683,26 +645,18 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements private void loadEngines() { List engines = mEnginesHelper.getEngines(); - updateUserEnabledEngines(engines); + CharSequence entries[] = new CharSequence[engines.size()]; + CharSequence values[] = new CharSequence[engines.size()]; - ArrayList entries = new ArrayList(); - ArrayList values = new ArrayList(); - StringBuilder enabledEngines = new StringBuilder(); - - for (EngineInfo engine : engines) { - Log.v(TAG, "Engine: " + engine); - if (mEnginesHelper.isEngineEnabled(engine.name)) { - entries.add(engine.label); - values.add(engine.name); - } + final int count = engines.size(); + for (int i = 0; i < count; ++i) { + final EngineInfo engine = engines.get(i); + entries[i] = engine.label; + values[i] = engine.name; } - - CharSequence entriesArray[] = new CharSequence[entries.size()]; - CharSequence valuesArray[] = new CharSequence[values.size()]; - - mDefaultSynthPref.setEntries(entries.toArray(entriesArray)); - mDefaultSynthPref.setEntryValues(values.toArray(valuesArray)); + mDefaultSynthPref.setEntries(entries); + mDefaultSynthPref.setEntryValues(values); // Set the selected engine based on the saved preference String selectedEngine = Settings.Secure.getString(getContentResolver(), TTS_DEFAULT_SYNTH); @@ -716,26 +670,51 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment implements } } - /* - * Write out the list of engines enabled by the user to a - * shared preference. - */ - private void updateUserEnabledEngines(List engines) { - StringBuilder enginesList = new StringBuilder(); - for (EngineInfo engine : engines) { - if (isEngineUserEnabled(engine.name)) { - if (enginesList.length() > 0) enginesList.append(' '); - enginesList.append(engine.name); + private void displayDataAlert(Preference pref, final String key) { + Log.v(TAG, "Displaying data alert for :" + key); + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + builder.setTitle(android.R.string.dialog_alert_title); + builder.setIcon(android.R.drawable.ic_dialog_alert); + builder.setMessage(getActivity().getString( + R.string.tts_engine_security_warning, pref.getTitle())); + builder.setCancelable(true); + builder.setPositiveButton(android.R.string.ok, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + updateDefaultEngine(key); + loadEngines(); + initEngineSpecificSettings(); + } + }); + builder.setNegativeButton(android.R.string.cancel, null); + + AlertDialog dialog = builder.create(); + dialog.show(); + } + + private void updateDefaultEngine(String engine) { + Log.v(TAG, "Updating default synth to : " + engine); + if (mTts != null) { + try { + mTts.shutdown(); + mTts = null; + } catch (Exception e) { + Log.e(TAG, "Error shutting down TTS engine" + e); } } - ContentResolver resolver = getContentResolver(); - Settings.Secure.putString(resolver, TTS_ENABLED_PLUGINS, enginesList.toString()); - } + mTts = new TextToSpeech(getActivity().getApplicationContext(), this, engine); + mEnableDemo = false; + mVoicesMissing = false; + updateWidgetState(); + checkVoiceData(); - private boolean isEngineUserEnabled(String engineName) { - String enginePref = KEY_PLUGIN_ENABLED_PREFIX + engineName; - return getPreferenceManager().getSharedPreferences().getBoolean(enginePref, false); + // Finally, persist this value to settings. + Settings.Secure.putString(getContentResolver(), TTS_DEFAULT_SYNTH, engine); + // .. and update the UI. + mDefaultSynthPref.setValue(engine); + + Log.v(TAG, "The default synth is now: " + engine); } }