blob: 488e117d10b42f8c53a000986ac6ff0400361f5f [file] [log] [blame]
Jean-Michel Trivied29a652009-06-05 18:37:29 -07001/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.settings;
18
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -070019import static android.provider.Settings.Secure.TTS_DEFAULT_COUNTRY;
Daisuke Miyakawa49a305e2010-09-13 17:52:13 -070020import static android.provider.Settings.Secure.TTS_DEFAULT_LANG;
21import static android.provider.Settings.Secure.TTS_DEFAULT_RATE;
Jean-Michel Trivi2acc02e2009-06-25 10:03:43 -070022import static android.provider.Settings.Secure.TTS_DEFAULT_SYNTH;
Daisuke Miyakawa49a305e2010-09-13 17:52:13 -070023import static android.provider.Settings.Secure.TTS_DEFAULT_VARIANT;
Charles Chenf47cce02010-03-17 17:33:23 -070024import static android.provider.Settings.Secure.TTS_ENABLED_PLUGINS;
Daisuke Miyakawa49a305e2010-09-13 17:52:13 -070025import static android.provider.Settings.Secure.TTS_USE_DEFAULTS;
Jean-Michel Trivied29a652009-06-05 18:37:29 -070026
Daisuke Miyakawa49a305e2010-09-13 17:52:13 -070027import android.app.Activity;
Charles Chen0a0eb5f2010-03-16 20:09:17 -070028import android.app.AlertDialog;
Jean-Michel Trivied29a652009-06-05 18:37:29 -070029import android.content.ContentResolver;
Daisuke Miyakawa49a305e2010-09-13 17:52:13 -070030import android.content.Context;
Charles Chen0a0eb5f2010-03-16 20:09:17 -070031import android.content.DialogInterface;
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -070032import android.content.Intent;
33import android.content.pm.ActivityInfo;
34import android.content.pm.PackageManager;
35import android.content.pm.ResolveInfo;
Jean-Michel Trivied29a652009-06-05 18:37:29 -070036import android.os.Bundle;
Daisuke Miyakawa49a305e2010-09-13 17:52:13 -070037import android.preference.CheckBoxPreference;
Jean-Michel Trivied29a652009-06-05 18:37:29 -070038import android.preference.ListPreference;
39import android.preference.Preference;
Charles Chen0a0eb5f2010-03-16 20:09:17 -070040import android.preference.Preference.OnPreferenceClickListener;
Charles Chen0a0eb5f2010-03-16 20:09:17 -070041import android.preference.PreferenceGroup;
42import android.preference.PreferenceScreen;
Jean-Michel Trivied29a652009-06-05 18:37:29 -070043import android.provider.Settings;
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -070044import android.provider.Settings.SettingNotFoundException;
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -070045import android.speech.tts.TextToSpeech;
Jean-Michel Trivied29a652009-06-05 18:37:29 -070046import android.util.Log;
47
Charles Chenc8298712010-02-10 13:58:23 -080048import java.util.ArrayList;
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -070049import java.util.List;
Jean-Michel Trivi44fbbea2009-07-06 14:04:54 -070050import java.util.Locale;
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -070051import java.util.StringTokenizer;
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -070052
Daisuke Miyakawa49a305e2010-09-13 17:52:13 -070053public class TextToSpeechSettings extends SettingsPreferenceFragment implements
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -070054 Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener,
55 TextToSpeech.OnInitListener {
Jean-Michel Trivied29a652009-06-05 18:37:29 -070056
57 private static final String TAG = "TextToSpeechSettings";
Jean-Michel Trivied29a652009-06-05 18:37:29 -070058
Charles Chen0a0eb5f2010-03-16 20:09:17 -070059 private static final String SYSTEM_TTS = "com.svox.pico";
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -070060 private static final String KEY_TTS_PLAY_EXAMPLE = "tts_play_example";
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -070061 private static final String KEY_TTS_INSTALL_DATA = "tts_install_data";
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -070062 private static final String KEY_TTS_USE_DEFAULT = "toggle_use_default_tts_settings";
Jean-Michel Trivied29a652009-06-05 18:37:29 -070063 private static final String KEY_TTS_DEFAULT_RATE = "tts_default_rate";
Jean-Michel Trivi80368622009-06-09 19:29:27 -070064 private static final String KEY_TTS_DEFAULT_LANG = "tts_default_lang";
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -070065 private static final String KEY_TTS_DEFAULT_COUNTRY = "tts_default_country";
66 private static final String KEY_TTS_DEFAULT_VARIANT = "tts_default_variant";
Charles Chen5dbc74a2009-12-07 12:08:13 -080067 private static final String KEY_TTS_DEFAULT_SYNTH = "tts_default_synth";
Charles Chen0a0eb5f2010-03-16 20:09:17 -070068
69 private static final String KEY_PLUGIN_ENABLED_PREFIX = "ENABLED_";
70 private static final String KEY_PLUGIN_SETTINGS_PREFIX = "SETTINGS_";
71
Jean-Michel Trivie8e23db2009-09-02 15:15:33 -070072 // TODO move default Locale values to TextToSpeech.Engine
73 private static final String DEFAULT_LANG_VAL = "eng";
74 private static final String DEFAULT_COUNTRY_VAL = "USA";
75 private static final String DEFAULT_VARIANT_VAL = "";
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -070076
77 private static final String LOCALE_DELIMITER = "-";
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -070078
Jean-Michel Trivi628431d2009-07-17 16:52:54 -070079 private static final String FALLBACK_TTS_DEFAULT_SYNTH =
Jean-Michel Trivi387dc0c2009-07-28 15:13:35 -070080 TextToSpeech.Engine.DEFAULT_SYNTH;
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -070081
82 private Preference mPlayExample = null;
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -070083 private Preference mInstallData = null;
Jean-Michel Trivied29a652009-06-05 18:37:29 -070084 private CheckBoxPreference mUseDefaultPref = null;
85 private ListPreference mDefaultRatePref = null;
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -070086 private ListPreference mDefaultLocPref = null;
Charles Chen5dbc74a2009-12-07 12:08:13 -080087 private ListPreference mDefaultSynthPref = null;
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -070088 private String mDefaultLanguage = null;
89 private String mDefaultCountry = null;
90 private String mDefaultLocVariant = null;
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -070091 private String mDefaultEng = "";
Jean-Michel Trivie8e23db2009-09-02 15:15:33 -070092 private int mDefaultRate = TextToSpeech.Engine.DEFAULT_RATE;
93
Jean-Michel Trivie8e23db2009-09-02 15:15:33 -070094 // Index of the current string to use for the demo.
95 private int mDemoStringIndex = 0;
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -070096
97 private boolean mEnableDemo = false;
Charles Chenc8298712010-02-10 13:58:23 -080098 private boolean mVoicesMissing = false;
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -070099
100 private TextToSpeech mTts = null;
Charles Chencf31e652010-04-07 14:26:31 -0700101 private boolean mTtsStarted = false;
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700102
103 /**
104 * Request code (arbitrary value) for voice data check through
105 * startActivityForResult.
106 */
107 private static final int VOICE_DATA_INTEGRITY_CHECK = 1977;
Charles Chen4df6c792010-01-22 11:17:40 -0800108 private static final int GET_SAMPLE_TEXT = 1983;
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700109
Jean-Michel Trivied29a652009-06-05 18:37:29 -0700110 @Override
Daisuke Miyakawa49a305e2010-09-13 17:52:13 -0700111 public void onCreate(Bundle savedInstanceState) {
Jean-Michel Trivied29a652009-06-05 18:37:29 -0700112 super.onCreate(savedInstanceState);
Jean-Michel Trivied29a652009-06-05 18:37:29 -0700113 addPreferencesFromResource(R.xml.tts_settings);
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700114
Daisuke Miyakawa49a305e2010-09-13 17:52:13 -0700115 final Activity activity = getActivity();
116 addEngineSpecificSettings(activity);
Charles Chen0a0eb5f2010-03-16 20:09:17 -0700117
Daisuke Miyakawa49a305e2010-09-13 17:52:13 -0700118 activity.setVolumeControlStream(TextToSpeech.Engine.DEFAULT_STREAM);
Jean-Michel Trivi6dde8962009-08-11 09:06:58 -0700119
Jean-Michel Trivi2acc02e2009-06-25 10:03:43 -0700120 mEnableDemo = false;
Charles Chencf31e652010-04-07 14:26:31 -0700121 mTtsStarted = false;
Charles Chenbe6e8272010-03-22 16:06:05 -0700122
Charles Chen8c8185b2010-04-08 16:51:35 -0700123 Locale currentLocale = Locale.getDefault();
124 mDefaultLanguage = currentLocale.getISO3Language();
125 mDefaultCountry = currentLocale.getISO3Country();
126 mDefaultLocVariant = currentLocale.getVariant();
127
Daisuke Miyakawa49a305e2010-09-13 17:52:13 -0700128 mTts = new TextToSpeech(activity, this);
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700129 }
Jean-Michel Trivi44fbbea2009-07-06 14:04:54 -0700130
131
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700132 @Override
Daisuke Miyakawa49a305e2010-09-13 17:52:13 -0700133 public void onStart() {
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700134 super.onStart();
Charles Chencf31e652010-04-07 14:26:31 -0700135 if (mTtsStarted){
136 // whenever we return to this screen, we don't know the state of the
137 // system, so we have to recheck that we can play the demo, or it must be disabled.
138 // TODO make the TTS service listen to "changes in the system", i.e. sd card un/mount
139 initClickers();
140 updateWidgetState();
141 checkVoiceData();
142 }
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700143 }
144
145
146 @Override
Daisuke Miyakawa49a305e2010-09-13 17:52:13 -0700147 public void onDestroy() {
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700148 super.onDestroy();
149 if (mTts != null) {
150 mTts.shutdown();
151 }
152 }
153
Charles Chen8c8185b2010-04-08 16:51:35 -0700154 @Override
Daisuke Miyakawa49a305e2010-09-13 17:52:13 -0700155 public void onPause() {
Charles Chen8c8185b2010-04-08 16:51:35 -0700156 super.onPause();
157 if ((mDefaultRatePref != null) && (mDefaultRatePref.getDialog() != null)) {
158 mDefaultRatePref.getDialog().dismiss();
159 }
160 if ((mDefaultLocPref != null) && (mDefaultLocPref.getDialog() != null)) {
161 mDefaultLocPref.getDialog().dismiss();
162 }
163 if ((mDefaultSynthPref != null) && (mDefaultSynthPref.getDialog() != null)) {
164 mDefaultSynthPref.getDialog().dismiss();
165 }
166 }
167
Daisuke Miyakawa49a305e2010-09-13 17:52:13 -0700168 private void addEngineSpecificSettings(Context context) {
Charles Chen0a0eb5f2010-03-16 20:09:17 -0700169 PreferenceGroup enginesCategory = (PreferenceGroup) findPreference("tts_engines_section");
170 Intent intent = new Intent("android.intent.action.START_TTS_ENGINE");
171 ResolveInfo[] enginesArray = new ResolveInfo[0];
172 PackageManager pm = getPackageManager();
173 enginesArray = pm.queryIntentActivities(intent, 0).toArray(enginesArray);
174 for (int i = 0; i < enginesArray.length; i++) {
175 String prefKey = "";
176 final String pluginPackageName = enginesArray[i].activityInfo.packageName;
177 if (!enginesArray[i].activityInfo.packageName.equals(SYSTEM_TTS)) {
Daisuke Miyakawa49a305e2010-09-13 17:52:13 -0700178 CheckBoxPreference chkbxPref = new CheckBoxPreference(context);
Charles Chen0a0eb5f2010-03-16 20:09:17 -0700179 prefKey = KEY_PLUGIN_ENABLED_PREFIX + pluginPackageName;
180 chkbxPref.setKey(prefKey);
181 chkbxPref.setTitle(enginesArray[i].loadLabel(pm));
182 enginesCategory.addPreference(chkbxPref);
183 }
184 if (pluginHasSettings(pluginPackageName)) {
Daisuke Miyakawa49a305e2010-09-13 17:52:13 -0700185 Preference pref = new Preference(context);
Charles Chen0a0eb5f2010-03-16 20:09:17 -0700186 prefKey = KEY_PLUGIN_SETTINGS_PREFIX + pluginPackageName;
187 pref.setKey(prefKey);
188 pref.setTitle(enginesArray[i].loadLabel(pm));
189 CharSequence settingsLabel = getResources().getString(
190 R.string.tts_engine_name_settings, enginesArray[i].loadLabel(pm));
191 pref.setSummary(settingsLabel);
192 pref.setOnPreferenceClickListener(new OnPreferenceClickListener(){
193 public boolean onPreferenceClick(Preference preference){
194 Intent i = new Intent();
195 i.setClassName(pluginPackageName,
196 pluginPackageName + ".EngineSettings");
197 startActivity(i);
198 return true;
199 }
200 });
201 enginesCategory.addPreference(pref);
202 }
203 }
204 }
205
206 private boolean pluginHasSettings(String pluginPackageName) {
207 PackageManager pm = getPackageManager();
208 Intent i = new Intent();
209 i.setClassName(pluginPackageName, pluginPackageName + ".EngineSettings");
210 if (pm.resolveActivity(i, PackageManager.MATCH_DEFAULT_ONLY) != null){
211 return true;
212 }
213 return false;
214 }
215
216
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700217 private void initClickers() {
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700218 mPlayExample = findPreference(KEY_TTS_PLAY_EXAMPLE);
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700219 mPlayExample.setOnPreferenceClickListener(this);
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700220
221 mInstallData = findPreference(KEY_TTS_INSTALL_DATA);
222 mInstallData.setOnPreferenceClickListener(this);
Jean-Michel Trivied29a652009-06-05 18:37:29 -0700223 }
224
225
226 private void initDefaultSettings() {
227 ContentResolver resolver = getContentResolver();
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700228
229 // Find the default TTS values in the settings, initialize and store the
230 // settings if they are not found.
Jean-Michel Trivied29a652009-06-05 18:37:29 -0700231
232 // "Use Defaults"
Jean-Michel Trivie8e23db2009-09-02 15:15:33 -0700233 int useDefault = 0;
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700234 mUseDefaultPref = (CheckBoxPreference) findPreference(KEY_TTS_USE_DEFAULT);
235 try {
Jean-Michel Trivie8e23db2009-09-02 15:15:33 -0700236 useDefault = Settings.Secure.getInt(resolver, TTS_USE_DEFAULTS);
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700237 } catch (SettingNotFoundException e) {
238 // "use default" setting not found, initialize it
Jean-Michel Trivie8e23db2009-09-02 15:15:33 -0700239 useDefault = TextToSpeech.Engine.USE_DEFAULTS;
240 Settings.Secure.putInt(resolver, TTS_USE_DEFAULTS, useDefault);
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700241 }
Jean-Michel Trivie8e23db2009-09-02 15:15:33 -0700242 mUseDefaultPref.setChecked(useDefault == 1);
Jean-Michel Trivied29a652009-06-05 18:37:29 -0700243 mUseDefaultPref.setOnPreferenceChangeListener(this);
244
Charles Chen5dbc74a2009-12-07 12:08:13 -0800245 // Default synthesis engine
246 mDefaultSynthPref = (ListPreference) findPreference(KEY_TTS_DEFAULT_SYNTH);
247 loadEngines();
248 mDefaultSynthPref.setOnPreferenceChangeListener(this);
Jean-Michel Trivi2acc02e2009-06-25 10:03:43 -0700249 String engine = Settings.Secure.getString(resolver, TTS_DEFAULT_SYNTH);
250 if (engine == null) {
251 // TODO move FALLBACK_TTS_DEFAULT_SYNTH to TextToSpeech
252 engine = FALLBACK_TTS_DEFAULT_SYNTH;
253 Settings.Secure.putString(resolver, TTS_DEFAULT_SYNTH, engine);
254 }
255 mDefaultEng = engine;
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700256
Jean-Michel Trivied29a652009-06-05 18:37:29 -0700257 // Default rate
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700258 mDefaultRatePref = (ListPreference) findPreference(KEY_TTS_DEFAULT_RATE);
259 try {
Jean-Michel Trivie8e23db2009-09-02 15:15:33 -0700260 mDefaultRate = Settings.Secure.getInt(resolver, TTS_DEFAULT_RATE);
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700261 } catch (SettingNotFoundException e) {
262 // default rate setting not found, initialize it
Jean-Michel Trivie8e23db2009-09-02 15:15:33 -0700263 mDefaultRate = TextToSpeech.Engine.DEFAULT_RATE;
264 Settings.Secure.putInt(resolver, TTS_DEFAULT_RATE, mDefaultRate);
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700265 }
Jean-Michel Trivie8e23db2009-09-02 15:15:33 -0700266 mDefaultRatePref.setValue(String.valueOf(mDefaultRate));
Jean-Michel Trivied29a652009-06-05 18:37:29 -0700267 mDefaultRatePref.setOnPreferenceChangeListener(this);
268
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700269 // Default language / country / variant : these three values map to a single ListPref
270 // representing the matching Locale
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700271 mDefaultLocPref = (ListPreference) findPreference(KEY_TTS_DEFAULT_LANG);
Jean-Michel Trivie8e23db2009-09-02 15:15:33 -0700272 initDefaultLang();
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700273 mDefaultLocPref.setOnPreferenceChangeListener(this);
Jean-Michel Trivied29a652009-06-05 18:37:29 -0700274 }
275
276
Jean-Michel Trivi2acc02e2009-06-25 10:03:43 -0700277 /**
278 * Ask the current default engine to launch the matching CHECK_TTS_DATA activity
279 * to check the required TTS files are properly installed.
280 */
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700281 private void checkVoiceData() {
282 PackageManager pm = getPackageManager();
283 Intent intent = new Intent();
Jean-Michel Trivi387dc0c2009-07-28 15:13:35 -0700284 intent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700285 List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0);
286 // query only the package that matches that of the default engine
287 for (int i = 0; i < resolveInfos.size(); i++) {
288 ActivityInfo currentActivityInfo = resolveInfos.get(i).activityInfo;
289 if (mDefaultEng.equals(currentActivityInfo.packageName)) {
290 intent.setClassName(mDefaultEng, currentActivityInfo.name);
291 this.startActivityForResult(intent, VOICE_DATA_INTEGRITY_CHECK);
292 }
293 }
294 }
295
296
297 /**
Jean-Michel Trivi2acc02e2009-06-25 10:03:43 -0700298 * Ask the current default engine to launch the matching INSTALL_TTS_DATA activity
299 * so the required TTS files are properly installed.
300 */
301 private void installVoiceData() {
302 PackageManager pm = getPackageManager();
303 Intent intent = new Intent();
Jean-Michel Trivi387dc0c2009-07-28 15:13:35 -0700304 intent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
Jean-Michel Trivi58ea43a2009-09-09 15:13:38 -0700305 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Jean-Michel Trivi2acc02e2009-06-25 10:03:43 -0700306 List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0);
307 // query only the package that matches that of the default engine
308 for (int i = 0; i < resolveInfos.size(); i++) {
309 ActivityInfo currentActivityInfo = resolveInfos.get(i).activityInfo;
310 if (mDefaultEng.equals(currentActivityInfo.packageName)) {
311 intent.setClassName(mDefaultEng, currentActivityInfo.name);
Jean-Michel Trivi58ea43a2009-09-09 15:13:38 -0700312 this.startActivity(intent);
Jean-Michel Trivi2acc02e2009-06-25 10:03:43 -0700313 }
314 }
315 }
316
Charles Chen4df6c792010-01-22 11:17:40 -0800317 /**
318 * Ask the current default engine to return a string of sample text to be
319 * spoken to the user.
320 */
321 private void getSampleText() {
322 PackageManager pm = getPackageManager();
323 Intent intent = new Intent();
324 // TODO (clchen): Replace Intent string with the actual
325 // Intent defined in the list of platform Intents.
326 intent.setAction("android.speech.tts.engine.GET_SAMPLE_TEXT");
327 intent.putExtra("language", mDefaultLanguage);
328 intent.putExtra("country", mDefaultCountry);
329 intent.putExtra("variant", mDefaultLocVariant);
330 List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0);
331 // query only the package that matches that of the default engine
332 for (int i = 0; i < resolveInfos.size(); i++) {
333 ActivityInfo currentActivityInfo = resolveInfos.get(i).activityInfo;
334 if (mDefaultEng.equals(currentActivityInfo.packageName)) {
335 intent.setClassName(mDefaultEng, currentActivityInfo.name);
336 this.startActivityForResult(intent, GET_SAMPLE_TEXT);
337 }
338 }
339 }
340
Jean-Michel Trivi2acc02e2009-06-25 10:03:43 -0700341
342 /**
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700343 * Called when the TTS engine is initialized.
344 */
345 public void onInit(int status) {
Jean-Michel Trivi387dc0c2009-07-28 15:13:35 -0700346 if (status == TextToSpeech.SUCCESS) {
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700347 mEnableDemo = true;
Jean-Michel Trivi7330a882010-02-17 12:50:44 -0800348 if (mDefaultLanguage == null) {
Charles Chencf3998b2010-02-11 18:13:42 -0800349 mDefaultLanguage = Locale.getDefault().getISO3Language();
350 }
Jean-Michel Trivi7330a882010-02-17 12:50:44 -0800351 if (mDefaultCountry == null) {
352 mDefaultCountry = Locale.getDefault().getISO3Country();
353 }
354 if (mDefaultLocVariant == null) {
355 mDefaultLocVariant = new String();
356 }
Charles Chencf3998b2010-02-11 18:13:42 -0800357 mTts.setLanguage(new Locale(mDefaultLanguage, mDefaultCountry, mDefaultLocVariant));
Daisuke Miyakawa49a305e2010-09-13 17:52:13 -0700358 mTts.setSpeechRate(mDefaultRate/100.0f);
Charles Chencf31e652010-04-07 14:26:31 -0700359 initDefaultSettings();
360 initClickers();
361 updateWidgetState();
362 checkVoiceData();
363 mTtsStarted = true;
364 Log.v(TAG, "TTS engine for settings screen initialized.");
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700365 } else {
366 Log.v(TAG, "TTS engine for settings screen failed to initialize successfully.");
367 mEnableDemo = false;
368 }
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700369 updateWidgetState();
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700370 }
371
372
373 /**
374 * Called when voice data integrity check returns
375 */
Daisuke Miyakawa49a305e2010-09-13 17:52:13 -0700376 @Override
377 public void onActivityResult(int requestCode, int resultCode, Intent data) {
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700378 if (requestCode == VOICE_DATA_INTEGRITY_CHECK) {
Charles Chend5f013a2010-02-18 10:11:25 -0800379 if (data == null){
380 // The CHECK_TTS_DATA activity for the plugin did not run properly;
381 // disable the preview and install controls and return.
382 mEnableDemo = false;
383 mVoicesMissing = false;
384 updateWidgetState();
385 return;
386 }
Charles Chenc8298712010-02-10 13:58:23 -0800387 ArrayList<String> available =
Charles Chen510bc4a2010-04-07 17:41:07 -0700388 data.getStringArrayListExtra(TextToSpeech.Engine.EXTRA_AVAILABLE_VOICES);
Charles Chenc8298712010-02-10 13:58:23 -0800389 ArrayList<String> unavailable =
Charles Chen510bc4a2010-04-07 17:41:07 -0700390 data.getStringArrayListExtra(TextToSpeech.Engine.EXTRA_UNAVAILABLE_VOICES);
Charles Chend5f013a2010-02-18 10:11:25 -0800391 if ((available == null) || (unavailable == null)){
392 // The CHECK_TTS_DATA activity for the plugin did not run properly;
393 // disable the preview and install controls and return.
394 mEnableDemo = false;
395 mVoicesMissing = false;
396 updateWidgetState();
397 return;
398 }
Charles Chenc8298712010-02-10 13:58:23 -0800399 if (available.size() > 0){
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700400 if (mTts == null) {
Daisuke Miyakawa49a305e2010-09-13 17:52:13 -0700401 mTts = new TextToSpeech(getActivity(), this);
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700402 }
Charles Chenc8298712010-02-10 13:58:23 -0800403 ListPreference ttsLanguagePref =
404 (ListPreference) findPreference("tts_default_lang");
405 CharSequence[] entries = new CharSequence[available.size()];
406 CharSequence[] entryValues = new CharSequence[available.size()];
Jean-Baptiste Queru6e61b212010-04-14 10:40:48 -0700407 int selectedLanguageIndex = -1;
408 String selectedLanguagePref = mDefaultLanguage;
409 if (mDefaultCountry.length() > 0) {
410 selectedLanguagePref = selectedLanguagePref + LOCALE_DELIMITER +
411 mDefaultCountry;
412 }
413 if (mDefaultLocVariant.length() > 0) {
414 selectedLanguagePref = selectedLanguagePref + LOCALE_DELIMITER +
415 mDefaultLocVariant;
416 }
417 for (int i = 0; i < available.size(); i++) {
Charles Chenc8298712010-02-10 13:58:23 -0800418 String[] langCountryVariant = available.get(i).split("-");
419 Locale loc = null;
420 if (langCountryVariant.length == 1){
421 loc = new Locale(langCountryVariant[0]);
422 } else if (langCountryVariant.length == 2){
423 loc = new Locale(langCountryVariant[0], langCountryVariant[1]);
424 } else if (langCountryVariant.length == 3){
425 loc = new Locale(langCountryVariant[0], langCountryVariant[1],
426 langCountryVariant[2]);
427 }
428 if (loc != null){
429 entries[i] = loc.getDisplayName();
430 entryValues[i] = available.get(i);
Jean-Baptiste Queru6e61b212010-04-14 10:40:48 -0700431 if (entryValues[i].equals(selectedLanguagePref)) {
432 selectedLanguageIndex = i;
433 }
Charles Chenc8298712010-02-10 13:58:23 -0800434 }
435 }
436 ttsLanguagePref.setEntries(entries);
437 ttsLanguagePref.setEntryValues(entryValues);
Jean-Baptiste Queru6e61b212010-04-14 10:40:48 -0700438 if (selectedLanguageIndex > -1) {
439 ttsLanguagePref.setValueIndex(selectedLanguageIndex);
440 }
Charles Chenc8298712010-02-10 13:58:23 -0800441 mEnableDemo = true;
Charles Chen473111b2010-04-06 15:50:42 -0700442 // Make sure that the default language can be used.
443 int languageResult = mTts.setLanguage(
444 new Locale(mDefaultLanguage, mDefaultCountry, mDefaultLocVariant));
445 if (languageResult < TextToSpeech.LANG_AVAILABLE){
446 Locale currentLocale = Locale.getDefault();
447 mDefaultLanguage = currentLocale.getISO3Language();
448 mDefaultCountry = currentLocale.getISO3Country();
449 mDefaultLocVariant = currentLocale.getVariant();
450 languageResult = mTts.setLanguage(
451 new Locale(mDefaultLanguage, mDefaultCountry, mDefaultLocVariant));
452 // If the default Locale isn't supported, just choose the first available
453 // language so that there is at least something.
454 if (languageResult < TextToSpeech.LANG_AVAILABLE){
455 parseLocaleInfo(ttsLanguagePref.getEntryValues()[0].toString());
456 mTts.setLanguage(
457 new Locale(mDefaultLanguage, mDefaultCountry, mDefaultLocVariant));
458 }
459 ContentResolver resolver = getContentResolver();
460 Settings.Secure.putString(resolver, TTS_DEFAULT_LANG, mDefaultLanguage);
461 Settings.Secure.putString(resolver, TTS_DEFAULT_COUNTRY, mDefaultCountry);
462 Settings.Secure.putString(resolver, TTS_DEFAULT_VARIANT, mDefaultLocVariant);
463 }
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700464 } else {
Jean-Michel Trivi2acc02e2009-06-25 10:03:43 -0700465 mEnableDemo = false;
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700466 }
Charles Chenc8298712010-02-10 13:58:23 -0800467
468 if (unavailable.size() > 0){
469 mVoicesMissing = true;
470 } else {
471 mVoicesMissing = false;
472 }
473
474 updateWidgetState();
Charles Chen4df6c792010-01-22 11:17:40 -0800475 } else if (requestCode == GET_SAMPLE_TEXT) {
476 if (resultCode == TextToSpeech.LANG_AVAILABLE) {
Daisuke Miyakawa49a305e2010-09-13 17:52:13 -0700477 String sample = getActivity().getString(R.string.tts_demo);
Charles Chenec05e712010-02-18 15:06:26 -0800478 if ((data != null) && (data.getStringExtra("sampleText") != null)) {
479 sample = data.getStringExtra("sampleText");
Charles Chend5f013a2010-02-18 10:11:25 -0800480 }
Charles Chen4df6c792010-01-22 11:17:40 -0800481 if (mTts != null) {
Charles Chen4df6c792010-01-22 11:17:40 -0800482 mTts.speak(sample, TextToSpeech.QUEUE_FLUSH, null);
483 }
484 } else {
485 // TODO: Display an error here to the user.
486 Log.e(TAG, "Did not have a sample string for the requested language");
487 }
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700488 }
489 }
490
Jean-Michel Trivied29a652009-06-05 18:37:29 -0700491 public boolean onPreferenceChange(Preference preference, Object objValue) {
492 if (KEY_TTS_USE_DEFAULT.equals(preference.getKey())) {
493 // "Use Defaults"
494 int value = (Boolean)objValue ? 1 : 0;
Jean-Michel Trivi80368622009-06-09 19:29:27 -0700495 Settings.Secure.putInt(getContentResolver(), TTS_USE_DEFAULTS,
Jean-Michel Trivied29a652009-06-05 18:37:29 -0700496 value);
497 Log.i(TAG, "TTS use default settings is "+objValue.toString());
498 } else if (KEY_TTS_DEFAULT_RATE.equals(preference.getKey())) {
499 // Default rate
Jean-Michel Trivie8e23db2009-09-02 15:15:33 -0700500 mDefaultRate = Integer.parseInt((String) objValue);
Jean-Michel Trivied29a652009-06-05 18:37:29 -0700501 try {
Jean-Michel Trivi44fbbea2009-07-06 14:04:54 -0700502 Settings.Secure.putInt(getContentResolver(),
Jean-Michel Trivie8e23db2009-09-02 15:15:33 -0700503 TTS_DEFAULT_RATE, mDefaultRate);
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700504 if (mTts != null) {
Daisuke Miyakawa49a305e2010-09-13 17:52:13 -0700505 mTts.setSpeechRate(mDefaultRate/100.0f);
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700506 }
Jean-Michel Trivie8e23db2009-09-02 15:15:33 -0700507 Log.i(TAG, "TTS default rate is " + mDefaultRate);
Jean-Michel Trivied29a652009-06-05 18:37:29 -0700508 } catch (NumberFormatException e) {
509 Log.e(TAG, "could not persist default TTS rate setting", e);
510 }
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700511 } else if (KEY_TTS_DEFAULT_LANG.equals(preference.getKey())) {
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700512 // Default locale
513 ContentResolver resolver = getContentResolver();
514 parseLocaleInfo((String) objValue);
515 Settings.Secure.putString(resolver, TTS_DEFAULT_LANG, mDefaultLanguage);
516 Settings.Secure.putString(resolver, TTS_DEFAULT_COUNTRY, mDefaultCountry);
517 Settings.Secure.putString(resolver, TTS_DEFAULT_VARIANT, mDefaultLocVariant);
518 Log.v(TAG, "TTS default lang/country/variant set to "
519 + mDefaultLanguage + "/" + mDefaultCountry + "/" + mDefaultLocVariant);
Jean-Michel Trivi628431d2009-07-17 16:52:54 -0700520 if (mTts != null) {
Charles Chencf3998b2010-02-11 18:13:42 -0800521 mTts.setLanguage(new Locale(mDefaultLanguage, mDefaultCountry, mDefaultLocVariant));
Jean-Michel Trivi628431d2009-07-17 16:52:54 -0700522 }
Jean-Michel Trivie8e23db2009-09-02 15:15:33 -0700523 int newIndex = mDefaultLocPref.findIndexOfValue((String)objValue);
524 Log.v("Settings", " selected is " + newIndex);
525 mDemoStringIndex = newIndex > -1 ? newIndex : 0;
Charles Chen5dbc74a2009-12-07 12:08:13 -0800526 } else if (KEY_TTS_DEFAULT_SYNTH.equals(preference.getKey())) {
Charles Chen5dbc74a2009-12-07 12:08:13 -0800527 mDefaultEng = objValue.toString();
528 Settings.Secure.putString(getContentResolver(), TTS_DEFAULT_SYNTH, mDefaultEng);
529 if (mTts != null) {
530 mTts.setEngineByPackageName(mDefaultEng);
Charles Chencf3998b2010-02-11 18:13:42 -0800531 mEnableDemo = false;
532 mVoicesMissing = false;
533 updateWidgetState();
534 checkVoiceData();
Charles Chen5dbc74a2009-12-07 12:08:13 -0800535 }
536 Log.v("Settings", "The default synth is: " + objValue.toString());
Jean-Michel Trivied29a652009-06-05 18:37:29 -0700537 }
Jean-Michel Trivi44fbbea2009-07-06 14:04:54 -0700538
Jean-Michel Trivied29a652009-06-05 18:37:29 -0700539 return true;
540 }
Jean-Michel Trivi44fbbea2009-07-06 14:04:54 -0700541
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700542
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700543 /**
544 * Called when mPlayExample or mInstallData is clicked
545 */
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700546 public boolean onPreferenceClick(Preference preference) {
547 if (preference == mPlayExample) {
Charles Chen4df6c792010-01-22 11:17:40 -0800548 // Get the sample text from the TTS engine; onActivityResult will do
549 // the actual speaking
550 getSampleText();
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700551 return true;
552 }
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700553 if (preference == mInstallData) {
Jean-Michel Trivi2acc02e2009-06-25 10:03:43 -0700554 installVoiceData();
555 // quit this activity so it needs to be restarted after installation of the voice data
556 finish();
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700557 return true;
558 }
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700559 return false;
560 }
561
Charles Chen0a0eb5f2010-03-16 20:09:17 -0700562 @Override
563 public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
564 if (Utils.isMonkeyRunning()) {
565 return false;
566 }
567
568 if (preference instanceof CheckBoxPreference) {
569 final CheckBoxPreference chkPref = (CheckBoxPreference) preference;
570 if (!chkPref.getKey().equals(KEY_TTS_USE_DEFAULT)){
571 if (chkPref.isChecked()) {
572 chkPref.setChecked(false);
Daisuke Miyakawa49a305e2010-09-13 17:52:13 -0700573 AlertDialog d = (new AlertDialog.Builder(getActivity()))
Charles Chen0a0eb5f2010-03-16 20:09:17 -0700574 .setTitle(android.R.string.dialog_alert_title)
575 .setIcon(android.R.drawable.ic_dialog_alert)
Daisuke Miyakawa49a305e2010-09-13 17:52:13 -0700576 .setMessage(
577 getActivity().getString(R.string.tts_engine_security_warning,
Charles Chen0a0eb5f2010-03-16 20:09:17 -0700578 chkPref.getTitle()))
579 .setCancelable(true)
580 .setPositiveButton(android.R.string.ok,
581 new DialogInterface.OnClickListener() {
582 public void onClick(DialogInterface dialog, int which) {
583 chkPref.setChecked(true);
584 loadEngines();
585 }
586 })
587 .setNegativeButton(android.R.string.cancel,
588 new DialogInterface.OnClickListener() {
589 public void onClick(DialogInterface dialog, int which) {
590 }
591 })
592 .create();
593 d.show();
594 } else {
595 loadEngines();
596 }
597 return true;
598 }
599 }
600 return false;
601 }
602
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700603
604 private void updateWidgetState() {
605 mPlayExample.setEnabled(mEnableDemo);
606 mUseDefaultPref.setEnabled(mEnableDemo);
607 mDefaultRatePref.setEnabled(mEnableDemo);
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700608 mDefaultLocPref.setEnabled(mEnableDemo);
609
Charles Chenc8298712010-02-10 13:58:23 -0800610 mInstallData.setEnabled(mVoicesMissing);
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700611 }
612
613
614 private void parseLocaleInfo(String locale) {
615 StringTokenizer tokenizer = new StringTokenizer(locale, LOCALE_DELIMITER);
616 mDefaultLanguage = "";
617 mDefaultCountry = "";
618 mDefaultLocVariant = "";
619 if (tokenizer.hasMoreTokens()) {
620 mDefaultLanguage = tokenizer.nextToken().trim();
621 }
622 if (tokenizer.hasMoreTokens()) {
623 mDefaultCountry = tokenizer.nextToken().trim();
624 }
625 if (tokenizer.hasMoreTokens()) {
626 mDefaultLocVariant = tokenizer.nextToken().trim();
627 }
628 }
629
630
Jean-Michel Trivie8e23db2009-09-02 15:15:33 -0700631 /**
632 * Initialize the default language in the UI and in the preferences.
633 * After this method has been invoked, the default language is a supported Locale.
634 */
635 private void initDefaultLang() {
636 // if there isn't already a default language preference
637 if (!hasLangPref()) {
638 // if the current Locale is supported
639 if (isCurrentLocSupported()) {
640 // then use the current Locale as the default language
641 useCurrentLocAsDefault();
642 } else {
643 // otherwise use a default supported Locale as the default language
644 useSupportedLocAsDefault();
645 }
Jean-Michel Trivi44fbbea2009-07-06 14:04:54 -0700646 }
647
Jean-Michel Trivie8e23db2009-09-02 15:15:33 -0700648 // Update the language preference list with the default language and the matching
649 // demo string (at this stage there is a default language pref)
650 ContentResolver resolver = getContentResolver();
651 mDefaultLanguage = Settings.Secure.getString(resolver, TTS_DEFAULT_LANG);
Charles Chen681d0b82010-04-12 12:06:30 -0700652 mDefaultCountry = Settings.Secure.getString(resolver, TTS_DEFAULT_COUNTRY);
653 mDefaultLocVariant = Settings.Secure.getString(resolver, TTS_DEFAULT_VARIANT);
Jean-Michel Trivi44fbbea2009-07-06 14:04:54 -0700654
Jean-Michel Trivie8e23db2009-09-02 15:15:33 -0700655 // update the demo string
656 mDemoStringIndex = mDefaultLocPref.findIndexOfValue(mDefaultLanguage + LOCALE_DELIMITER
657 + mDefaultCountry);
Charles Chen8a37e612010-02-04 15:52:30 -0800658 if (mDemoStringIndex > -1){
659 mDefaultLocPref.setValueIndex(mDemoStringIndex);
660 }
Jean-Michel Trivie8e23db2009-09-02 15:15:33 -0700661 }
662
663 /**
664 * (helper function for initDefaultLang() )
665 * Returns whether there is a default language in the TTS settings.
666 */
667 private boolean hasLangPref() {
Jean-Baptiste Queru6e61b212010-04-14 10:40:48 -0700668 ContentResolver resolver = getContentResolver();
669 String language = Settings.Secure.getString(resolver, TTS_DEFAULT_LANG);
670 if ((language == null) || (language.length() < 1)) {
671 return false;
672 }
673 String country = Settings.Secure.getString(resolver, TTS_DEFAULT_COUNTRY);
674 if (country == null) {
675 return false;
676 }
677 String variant = Settings.Secure.getString(resolver, TTS_DEFAULT_VARIANT);
678 if (variant == null) {
679 return false;
680 }
681 return true;
Jean-Michel Trivie8e23db2009-09-02 15:15:33 -0700682 }
683
684 /**
685 * (helper function for initDefaultLang() )
686 * Returns whether the current Locale is supported by this Settings screen
687 */
688 private boolean isCurrentLocSupported() {
689 String currentLocID = Locale.getDefault().getISO3Language() + LOCALE_DELIMITER
690 + Locale.getDefault().getISO3Country();
691 return (mDefaultLocPref.findIndexOfValue(currentLocID) > -1);
692 }
693
694 /**
695 * (helper function for initDefaultLang() )
696 * Sets the default language in TTS settings to be the current Locale.
697 * This should only be used after checking that the current Locale is supported.
698 */
699 private void useCurrentLocAsDefault() {
700 Locale currentLocale = Locale.getDefault();
701 ContentResolver resolver = getContentResolver();
702 Settings.Secure.putString(resolver, TTS_DEFAULT_LANG, currentLocale.getISO3Language());
703 Settings.Secure.putString(resolver, TTS_DEFAULT_COUNTRY, currentLocale.getISO3Country());
704 Settings.Secure.putString(resolver, TTS_DEFAULT_VARIANT, currentLocale.getVariant());
705 }
706
707 /**
708 * (helper function for initDefaultLang() )
709 * Sets the default language in TTS settings to be one known to be supported
710 */
711 private void useSupportedLocAsDefault() {
712 ContentResolver resolver = getContentResolver();
713 Settings.Secure.putString(resolver, TTS_DEFAULT_LANG, DEFAULT_LANG_VAL);
714 Settings.Secure.putString(resolver, TTS_DEFAULT_COUNTRY, DEFAULT_COUNTRY_VAL);
715 Settings.Secure.putString(resolver, TTS_DEFAULT_VARIANT, DEFAULT_VARIANT_VAL);
Jean-Michel Trivi44fbbea2009-07-06 14:04:54 -0700716 }
717
Charles Chen5dbc74a2009-12-07 12:08:13 -0800718
Charles Chen0a0eb5f2010-03-16 20:09:17 -0700719 private void loadEngines() {
Charles Chen8c8185b2010-04-08 16:51:35 -0700720 mDefaultSynthPref = (ListPreference) findPreference(KEY_TTS_DEFAULT_SYNTH);
Charles Chen5dbc74a2009-12-07 12:08:13 -0800721
Charles Chen0a0eb5f2010-03-16 20:09:17 -0700722 // TODO (clchen): Try to see if it is possible to be more efficient here
723 // and not search for plugins again.
724 Intent intent = new Intent("android.intent.action.START_TTS_ENGINE");
725 ResolveInfo[] enginesArray = new ResolveInfo[0];
726 PackageManager pm = getPackageManager();
727 enginesArray = pm.queryIntentActivities(intent, 0).toArray(enginesArray);
728 ArrayList<CharSequence> entries = new ArrayList<CharSequence>();
729 ArrayList<CharSequence> values = new ArrayList<CharSequence>();
Charles Chenf47cce02010-03-17 17:33:23 -0700730 String enabledEngines = "";
Charles Chen0a0eb5f2010-03-16 20:09:17 -0700731 for (int i = 0; i < enginesArray.length; i++) {
Charles Chenf47cce02010-03-17 17:33:23 -0700732 String pluginPackageName = enginesArray[i].activityInfo.packageName;
733 if (pluginPackageName.equals(SYSTEM_TTS)) {
Charles Chen0a0eb5f2010-03-16 20:09:17 -0700734 entries.add(enginesArray[i].loadLabel(pm));
Charles Chenf47cce02010-03-17 17:33:23 -0700735 values.add(pluginPackageName);
Charles Chen0a0eb5f2010-03-16 20:09:17 -0700736 } else {
737 CheckBoxPreference pref = (CheckBoxPreference) findPreference(
Charles Chenf47cce02010-03-17 17:33:23 -0700738 KEY_PLUGIN_ENABLED_PREFIX + pluginPackageName);
Charles Chen0a0eb5f2010-03-16 20:09:17 -0700739 if ((pref != null) && pref.isChecked()){
740 entries.add(enginesArray[i].loadLabel(pm));
Charles Chenf47cce02010-03-17 17:33:23 -0700741 values.add(pluginPackageName);
742 enabledEngines = enabledEngines + pluginPackageName + " ";
Charles Chen0a0eb5f2010-03-16 20:09:17 -0700743 }
744 }
745 }
Charles Chenf47cce02010-03-17 17:33:23 -0700746 ContentResolver resolver = getContentResolver();
747 Settings.Secure.putString(resolver, TTS_ENABLED_PLUGINS, enabledEngines);
Charles Chen5dbc74a2009-12-07 12:08:13 -0800748
Charles Chen0a0eb5f2010-03-16 20:09:17 -0700749 CharSequence entriesArray[] = new CharSequence[entries.size()];
750 CharSequence valuesArray[] = new CharSequence[values.size()];
751
Charles Chen8c8185b2010-04-08 16:51:35 -0700752 mDefaultSynthPref.setEntries(entries.toArray(entriesArray));
753 mDefaultSynthPref.setEntryValues(values.toArray(valuesArray));
Charles Chenbe6e8272010-03-22 16:06:05 -0700754
755 // Set the selected engine based on the saved preference
756 String selectedEngine = Settings.Secure.getString(getContentResolver(), TTS_DEFAULT_SYNTH);
Charles Chen8c8185b2010-04-08 16:51:35 -0700757 int selectedEngineIndex = mDefaultSynthPref.findIndexOfValue(selectedEngine);
Charles Chenbe6e8272010-03-22 16:06:05 -0700758 if (selectedEngineIndex == -1){
Charles Chen8c8185b2010-04-08 16:51:35 -0700759 selectedEngineIndex = mDefaultSynthPref.findIndexOfValue(SYSTEM_TTS);
Charles Chenbe6e8272010-03-22 16:06:05 -0700760 }
Charles Chen8c8185b2010-04-08 16:51:35 -0700761 mDefaultSynthPref.setValueIndex(selectedEngineIndex);
Charles Chen5dbc74a2009-12-07 12:08:13 -0800762 }
Charles Chen5dbc74a2009-12-07 12:08:13 -0800763
Jean-Michel Trivied29a652009-06-05 18:37:29 -0700764}