blob: 62edac9490b6da55c0c80af5b949a1cda25aa6e0 [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.PreferenceGroup;
41import android.preference.PreferenceScreen;
Amith Yamasani02cf71a2010-09-21 15:48:52 -070042import android.preference.Preference.OnPreferenceClickListener;
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);
Amith Yamasani02cf71a2010-09-21 15:48:52 -0700129 initClickers();
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700130 }
Jean-Michel Trivi44fbbea2009-07-06 14:04:54 -0700131
132
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700133 @Override
Daisuke Miyakawa49a305e2010-09-13 17:52:13 -0700134 public void onStart() {
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700135 super.onStart();
Charles Chencf31e652010-04-07 14:26:31 -0700136 if (mTtsStarted){
137 // whenever we return to this screen, we don't know the state of the
138 // system, so we have to recheck that we can play the demo, or it must be disabled.
139 // TODO make the TTS service listen to "changes in the system", i.e. sd card un/mount
Charles Chencf31e652010-04-07 14:26:31 -0700140 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);
Jean-Michel Trivi8863ce92011-03-02 15:47:52 -0800268 // apply the default rate so the TTS demo in the Settings screen uses it, even if
269 // the use of default settings is not enforced
270 mTts.setSpeechRate(mDefaultRate/100.0f);
Jean-Michel Trivied29a652009-06-05 18:37:29 -0700271
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700272 // Default language / country / variant : these three values map to a single ListPref
273 // representing the matching Locale
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700274 mDefaultLocPref = (ListPreference) findPreference(KEY_TTS_DEFAULT_LANG);
Jean-Michel Trivie8e23db2009-09-02 15:15:33 -0700275 initDefaultLang();
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700276 mDefaultLocPref.setOnPreferenceChangeListener(this);
Jean-Michel Trivied29a652009-06-05 18:37:29 -0700277 }
278
279
Jean-Michel Trivi2acc02e2009-06-25 10:03:43 -0700280 /**
281 * Ask the current default engine to launch the matching CHECK_TTS_DATA activity
282 * to check the required TTS files are properly installed.
283 */
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700284 private void checkVoiceData() {
285 PackageManager pm = getPackageManager();
286 Intent intent = new Intent();
Jean-Michel Trivi387dc0c2009-07-28 15:13:35 -0700287 intent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700288 List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0);
289 // query only the package that matches that of the default engine
290 for (int i = 0; i < resolveInfos.size(); i++) {
291 ActivityInfo currentActivityInfo = resolveInfos.get(i).activityInfo;
292 if (mDefaultEng.equals(currentActivityInfo.packageName)) {
293 intent.setClassName(mDefaultEng, currentActivityInfo.name);
294 this.startActivityForResult(intent, VOICE_DATA_INTEGRITY_CHECK);
295 }
296 }
297 }
298
299
300 /**
Jean-Michel Trivi2acc02e2009-06-25 10:03:43 -0700301 * Ask the current default engine to launch the matching INSTALL_TTS_DATA activity
302 * so the required TTS files are properly installed.
303 */
304 private void installVoiceData() {
305 PackageManager pm = getPackageManager();
306 Intent intent = new Intent();
Jean-Michel Trivi387dc0c2009-07-28 15:13:35 -0700307 intent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
Jean-Michel Trivi58ea43a2009-09-09 15:13:38 -0700308 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Jean-Michel Trivi2acc02e2009-06-25 10:03:43 -0700309 List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0);
310 // query only the package that matches that of the default engine
311 for (int i = 0; i < resolveInfos.size(); i++) {
312 ActivityInfo currentActivityInfo = resolveInfos.get(i).activityInfo;
313 if (mDefaultEng.equals(currentActivityInfo.packageName)) {
314 intent.setClassName(mDefaultEng, currentActivityInfo.name);
Jean-Michel Trivi58ea43a2009-09-09 15:13:38 -0700315 this.startActivity(intent);
Jean-Michel Trivi2acc02e2009-06-25 10:03:43 -0700316 }
317 }
318 }
319
Charles Chen4df6c792010-01-22 11:17:40 -0800320 /**
321 * Ask the current default engine to return a string of sample text to be
322 * spoken to the user.
323 */
324 private void getSampleText() {
325 PackageManager pm = getPackageManager();
326 Intent intent = new Intent();
327 // TODO (clchen): Replace Intent string with the actual
328 // Intent defined in the list of platform Intents.
329 intent.setAction("android.speech.tts.engine.GET_SAMPLE_TEXT");
330 intent.putExtra("language", mDefaultLanguage);
331 intent.putExtra("country", mDefaultCountry);
332 intent.putExtra("variant", mDefaultLocVariant);
333 List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0);
334 // query only the package that matches that of the default engine
335 for (int i = 0; i < resolveInfos.size(); i++) {
336 ActivityInfo currentActivityInfo = resolveInfos.get(i).activityInfo;
337 if (mDefaultEng.equals(currentActivityInfo.packageName)) {
338 intent.setClassName(mDefaultEng, currentActivityInfo.name);
339 this.startActivityForResult(intent, GET_SAMPLE_TEXT);
340 }
341 }
342 }
343
Jean-Michel Trivi2acc02e2009-06-25 10:03:43 -0700344
345 /**
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700346 * Called when the TTS engine is initialized.
347 */
348 public void onInit(int status) {
Jean-Michel Trivi387dc0c2009-07-28 15:13:35 -0700349 if (status == TextToSpeech.SUCCESS) {
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700350 mEnableDemo = true;
Jean-Michel Trivi7330a882010-02-17 12:50:44 -0800351 if (mDefaultLanguage == null) {
Charles Chencf3998b2010-02-11 18:13:42 -0800352 mDefaultLanguage = Locale.getDefault().getISO3Language();
353 }
Jean-Michel Trivi7330a882010-02-17 12:50:44 -0800354 if (mDefaultCountry == null) {
355 mDefaultCountry = Locale.getDefault().getISO3Country();
356 }
357 if (mDefaultLocVariant == null) {
358 mDefaultLocVariant = new String();
359 }
Charles Chencf3998b2010-02-11 18:13:42 -0800360 mTts.setLanguage(new Locale(mDefaultLanguage, mDefaultCountry, mDefaultLocVariant));
Charles Chencf31e652010-04-07 14:26:31 -0700361 initDefaultSettings();
Charles Chencf31e652010-04-07 14:26:31 -0700362 updateWidgetState();
363 checkVoiceData();
364 mTtsStarted = true;
365 Log.v(TAG, "TTS engine for settings screen initialized.");
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700366 } else {
367 Log.v(TAG, "TTS engine for settings screen failed to initialize successfully.");
368 mEnableDemo = false;
369 }
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700370 updateWidgetState();
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700371 }
372
373
374 /**
375 * Called when voice data integrity check returns
376 */
Daisuke Miyakawa49a305e2010-09-13 17:52:13 -0700377 @Override
378 public void onActivityResult(int requestCode, int resultCode, Intent data) {
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700379 if (requestCode == VOICE_DATA_INTEGRITY_CHECK) {
Charles Chend5f013a2010-02-18 10:11:25 -0800380 if (data == null){
381 // The CHECK_TTS_DATA activity for the plugin did not run properly;
382 // disable the preview and install controls and return.
383 mEnableDemo = false;
384 mVoicesMissing = false;
385 updateWidgetState();
386 return;
387 }
Charles Chenc8298712010-02-10 13:58:23 -0800388 ArrayList<String> available =
Charles Chen510bc4a2010-04-07 17:41:07 -0700389 data.getStringArrayListExtra(TextToSpeech.Engine.EXTRA_AVAILABLE_VOICES);
Charles Chenc8298712010-02-10 13:58:23 -0800390 ArrayList<String> unavailable =
Charles Chen510bc4a2010-04-07 17:41:07 -0700391 data.getStringArrayListExtra(TextToSpeech.Engine.EXTRA_UNAVAILABLE_VOICES);
Charles Chend5f013a2010-02-18 10:11:25 -0800392 if ((available == null) || (unavailable == null)){
393 // The CHECK_TTS_DATA activity for the plugin did not run properly;
394 // disable the preview and install controls and return.
395 mEnableDemo = false;
396 mVoicesMissing = false;
397 updateWidgetState();
398 return;
399 }
Charles Chenc8298712010-02-10 13:58:23 -0800400 if (available.size() > 0){
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700401 if (mTts == null) {
Daisuke Miyakawa49a305e2010-09-13 17:52:13 -0700402 mTts = new TextToSpeech(getActivity(), this);
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700403 }
Charles Chenc8298712010-02-10 13:58:23 -0800404 ListPreference ttsLanguagePref =
405 (ListPreference) findPreference("tts_default_lang");
406 CharSequence[] entries = new CharSequence[available.size()];
407 CharSequence[] entryValues = new CharSequence[available.size()];
Jean-Baptiste Queru6e61b212010-04-14 10:40:48 -0700408 int selectedLanguageIndex = -1;
409 String selectedLanguagePref = mDefaultLanguage;
410 if (mDefaultCountry.length() > 0) {
411 selectedLanguagePref = selectedLanguagePref + LOCALE_DELIMITER +
412 mDefaultCountry;
413 }
414 if (mDefaultLocVariant.length() > 0) {
415 selectedLanguagePref = selectedLanguagePref + LOCALE_DELIMITER +
416 mDefaultLocVariant;
417 }
418 for (int i = 0; i < available.size(); i++) {
Charles Chenc8298712010-02-10 13:58:23 -0800419 String[] langCountryVariant = available.get(i).split("-");
420 Locale loc = null;
421 if (langCountryVariant.length == 1){
422 loc = new Locale(langCountryVariant[0]);
423 } else if (langCountryVariant.length == 2){
424 loc = new Locale(langCountryVariant[0], langCountryVariant[1]);
425 } else if (langCountryVariant.length == 3){
426 loc = new Locale(langCountryVariant[0], langCountryVariant[1],
427 langCountryVariant[2]);
428 }
429 if (loc != null){
430 entries[i] = loc.getDisplayName();
431 entryValues[i] = available.get(i);
Jean-Baptiste Queru6e61b212010-04-14 10:40:48 -0700432 if (entryValues[i].equals(selectedLanguagePref)) {
433 selectedLanguageIndex = i;
434 }
Charles Chenc8298712010-02-10 13:58:23 -0800435 }
436 }
437 ttsLanguagePref.setEntries(entries);
438 ttsLanguagePref.setEntryValues(entryValues);
Jean-Baptiste Queru6e61b212010-04-14 10:40:48 -0700439 if (selectedLanguageIndex > -1) {
440 ttsLanguagePref.setValueIndex(selectedLanguageIndex);
441 }
Charles Chenc8298712010-02-10 13:58:23 -0800442 mEnableDemo = true;
Charles Chen473111b2010-04-06 15:50:42 -0700443 // Make sure that the default language can be used.
444 int languageResult = mTts.setLanguage(
445 new Locale(mDefaultLanguage, mDefaultCountry, mDefaultLocVariant));
446 if (languageResult < TextToSpeech.LANG_AVAILABLE){
447 Locale currentLocale = Locale.getDefault();
448 mDefaultLanguage = currentLocale.getISO3Language();
449 mDefaultCountry = currentLocale.getISO3Country();
450 mDefaultLocVariant = currentLocale.getVariant();
451 languageResult = mTts.setLanguage(
452 new Locale(mDefaultLanguage, mDefaultCountry, mDefaultLocVariant));
453 // If the default Locale isn't supported, just choose the first available
454 // language so that there is at least something.
455 if (languageResult < TextToSpeech.LANG_AVAILABLE){
456 parseLocaleInfo(ttsLanguagePref.getEntryValues()[0].toString());
457 mTts.setLanguage(
458 new Locale(mDefaultLanguage, mDefaultCountry, mDefaultLocVariant));
459 }
460 ContentResolver resolver = getContentResolver();
461 Settings.Secure.putString(resolver, TTS_DEFAULT_LANG, mDefaultLanguage);
462 Settings.Secure.putString(resolver, TTS_DEFAULT_COUNTRY, mDefaultCountry);
463 Settings.Secure.putString(resolver, TTS_DEFAULT_VARIANT, mDefaultLocVariant);
464 }
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700465 } else {
Jean-Michel Trivi2acc02e2009-06-25 10:03:43 -0700466 mEnableDemo = false;
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700467 }
Charles Chenc8298712010-02-10 13:58:23 -0800468
469 if (unavailable.size() > 0){
470 mVoicesMissing = true;
471 } else {
472 mVoicesMissing = false;
473 }
474
475 updateWidgetState();
Charles Chen4df6c792010-01-22 11:17:40 -0800476 } else if (requestCode == GET_SAMPLE_TEXT) {
477 if (resultCode == TextToSpeech.LANG_AVAILABLE) {
Daisuke Miyakawa49a305e2010-09-13 17:52:13 -0700478 String sample = getActivity().getString(R.string.tts_demo);
Charles Chenec05e712010-02-18 15:06:26 -0800479 if ((data != null) && (data.getStringExtra("sampleText") != null)) {
480 sample = data.getStringExtra("sampleText");
Charles Chend5f013a2010-02-18 10:11:25 -0800481 }
Charles Chen4df6c792010-01-22 11:17:40 -0800482 if (mTts != null) {
Charles Chen4df6c792010-01-22 11:17:40 -0800483 mTts.speak(sample, TextToSpeech.QUEUE_FLUSH, null);
484 }
485 } else {
486 // TODO: Display an error here to the user.
487 Log.e(TAG, "Did not have a sample string for the requested language");
488 }
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700489 }
490 }
491
Jean-Michel Trivied29a652009-06-05 18:37:29 -0700492 public boolean onPreferenceChange(Preference preference, Object objValue) {
493 if (KEY_TTS_USE_DEFAULT.equals(preference.getKey())) {
494 // "Use Defaults"
495 int value = (Boolean)objValue ? 1 : 0;
Jean-Michel Trivi80368622009-06-09 19:29:27 -0700496 Settings.Secure.putInt(getContentResolver(), TTS_USE_DEFAULTS,
Jean-Michel Trivied29a652009-06-05 18:37:29 -0700497 value);
498 Log.i(TAG, "TTS use default settings is "+objValue.toString());
499 } else if (KEY_TTS_DEFAULT_RATE.equals(preference.getKey())) {
500 // Default rate
Jean-Michel Trivie8e23db2009-09-02 15:15:33 -0700501 mDefaultRate = Integer.parseInt((String) objValue);
Jean-Michel Trivied29a652009-06-05 18:37:29 -0700502 try {
Jean-Michel Trivi44fbbea2009-07-06 14:04:54 -0700503 Settings.Secure.putInt(getContentResolver(),
Jean-Michel Trivie8e23db2009-09-02 15:15:33 -0700504 TTS_DEFAULT_RATE, mDefaultRate);
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700505 if (mTts != null) {
Daisuke Miyakawa49a305e2010-09-13 17:52:13 -0700506 mTts.setSpeechRate(mDefaultRate/100.0f);
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700507 }
Jean-Michel Trivie8e23db2009-09-02 15:15:33 -0700508 Log.i(TAG, "TTS default rate is " + mDefaultRate);
Jean-Michel Trivied29a652009-06-05 18:37:29 -0700509 } catch (NumberFormatException e) {
510 Log.e(TAG, "could not persist default TTS rate setting", e);
511 }
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700512 } else if (KEY_TTS_DEFAULT_LANG.equals(preference.getKey())) {
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700513 // Default locale
514 ContentResolver resolver = getContentResolver();
515 parseLocaleInfo((String) objValue);
516 Settings.Secure.putString(resolver, TTS_DEFAULT_LANG, mDefaultLanguage);
517 Settings.Secure.putString(resolver, TTS_DEFAULT_COUNTRY, mDefaultCountry);
518 Settings.Secure.putString(resolver, TTS_DEFAULT_VARIANT, mDefaultLocVariant);
519 Log.v(TAG, "TTS default lang/country/variant set to "
520 + mDefaultLanguage + "/" + mDefaultCountry + "/" + mDefaultLocVariant);
Jean-Michel Trivi628431d2009-07-17 16:52:54 -0700521 if (mTts != null) {
Charles Chencf3998b2010-02-11 18:13:42 -0800522 mTts.setLanguage(new Locale(mDefaultLanguage, mDefaultCountry, mDefaultLocVariant));
Jean-Michel Trivi628431d2009-07-17 16:52:54 -0700523 }
Jean-Michel Trivie8e23db2009-09-02 15:15:33 -0700524 int newIndex = mDefaultLocPref.findIndexOfValue((String)objValue);
525 Log.v("Settings", " selected is " + newIndex);
526 mDemoStringIndex = newIndex > -1 ? newIndex : 0;
Charles Chen5dbc74a2009-12-07 12:08:13 -0800527 } else if (KEY_TTS_DEFAULT_SYNTH.equals(preference.getKey())) {
Charles Chen5dbc74a2009-12-07 12:08:13 -0800528 mDefaultEng = objValue.toString();
529 Settings.Secure.putString(getContentResolver(), TTS_DEFAULT_SYNTH, mDefaultEng);
530 if (mTts != null) {
531 mTts.setEngineByPackageName(mDefaultEng);
Charles Chencf3998b2010-02-11 18:13:42 -0800532 mEnableDemo = false;
533 mVoicesMissing = false;
534 updateWidgetState();
535 checkVoiceData();
Charles Chen5dbc74a2009-12-07 12:08:13 -0800536 }
537 Log.v("Settings", "The default synth is: " + objValue.toString());
Jean-Michel Trivied29a652009-06-05 18:37:29 -0700538 }
Jean-Michel Trivi44fbbea2009-07-06 14:04:54 -0700539
Jean-Michel Trivied29a652009-06-05 18:37:29 -0700540 return true;
541 }
Jean-Michel Trivi44fbbea2009-07-06 14:04:54 -0700542
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700543
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700544 /**
545 * Called when mPlayExample or mInstallData is clicked
546 */
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700547 public boolean onPreferenceClick(Preference preference) {
548 if (preference == mPlayExample) {
Charles Chen4df6c792010-01-22 11:17:40 -0800549 // Get the sample text from the TTS engine; onActivityResult will do
550 // the actual speaking
551 getSampleText();
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700552 return true;
553 }
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700554 if (preference == mInstallData) {
Jean-Michel Trivi2acc02e2009-06-25 10:03:43 -0700555 installVoiceData();
556 // quit this activity so it needs to be restarted after installation of the voice data
557 finish();
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700558 return true;
559 }
Jean-Michel Trivi74e565d2009-06-18 18:44:52 -0700560 return false;
561 }
562
Charles Chen0a0eb5f2010-03-16 20:09:17 -0700563 @Override
564 public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
565 if (Utils.isMonkeyRunning()) {
566 return false;
567 }
568
569 if (preference instanceof CheckBoxPreference) {
570 final CheckBoxPreference chkPref = (CheckBoxPreference) preference;
571 if (!chkPref.getKey().equals(KEY_TTS_USE_DEFAULT)){
572 if (chkPref.isChecked()) {
573 chkPref.setChecked(false);
Daisuke Miyakawa49a305e2010-09-13 17:52:13 -0700574 AlertDialog d = (new AlertDialog.Builder(getActivity()))
Charles Chen0a0eb5f2010-03-16 20:09:17 -0700575 .setTitle(android.R.string.dialog_alert_title)
576 .setIcon(android.R.drawable.ic_dialog_alert)
Daisuke Miyakawa49a305e2010-09-13 17:52:13 -0700577 .setMessage(
578 getActivity().getString(R.string.tts_engine_security_warning,
Charles Chen0a0eb5f2010-03-16 20:09:17 -0700579 chkPref.getTitle()))
580 .setCancelable(true)
581 .setPositiveButton(android.R.string.ok,
582 new DialogInterface.OnClickListener() {
583 public void onClick(DialogInterface dialog, int which) {
584 chkPref.setChecked(true);
585 loadEngines();
586 }
587 })
588 .setNegativeButton(android.R.string.cancel,
589 new DialogInterface.OnClickListener() {
590 public void onClick(DialogInterface dialog, int which) {
591 }
592 })
593 .create();
594 d.show();
595 } else {
596 loadEngines();
597 }
598 return true;
599 }
600 }
601 return false;
602 }
603
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700604
605 private void updateWidgetState() {
606 mPlayExample.setEnabled(mEnableDemo);
607 mUseDefaultPref.setEnabled(mEnableDemo);
608 mDefaultRatePref.setEnabled(mEnableDemo);
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700609 mDefaultLocPref.setEnabled(mEnableDemo);
610
Charles Chenc8298712010-02-10 13:58:23 -0800611 mInstallData.setEnabled(mVoicesMissing);
Jean-Michel Trivi1e6a45a2009-06-22 16:03:40 -0700612 }
613
614
615 private void parseLocaleInfo(String locale) {
616 StringTokenizer tokenizer = new StringTokenizer(locale, LOCALE_DELIMITER);
617 mDefaultLanguage = "";
618 mDefaultCountry = "";
619 mDefaultLocVariant = "";
620 if (tokenizer.hasMoreTokens()) {
621 mDefaultLanguage = tokenizer.nextToken().trim();
622 }
623 if (tokenizer.hasMoreTokens()) {
624 mDefaultCountry = tokenizer.nextToken().trim();
625 }
626 if (tokenizer.hasMoreTokens()) {
627 mDefaultLocVariant = tokenizer.nextToken().trim();
628 }
629 }
630
631
Jean-Michel Trivie8e23db2009-09-02 15:15:33 -0700632 /**
633 * Initialize the default language in the UI and in the preferences.
634 * After this method has been invoked, the default language is a supported Locale.
635 */
636 private void initDefaultLang() {
637 // if there isn't already a default language preference
638 if (!hasLangPref()) {
639 // if the current Locale is supported
640 if (isCurrentLocSupported()) {
641 // then use the current Locale as the default language
642 useCurrentLocAsDefault();
643 } else {
644 // otherwise use a default supported Locale as the default language
645 useSupportedLocAsDefault();
646 }
Jean-Michel Trivi44fbbea2009-07-06 14:04:54 -0700647 }
648
Jean-Michel Trivie8e23db2009-09-02 15:15:33 -0700649 // Update the language preference list with the default language and the matching
650 // demo string (at this stage there is a default language pref)
651 ContentResolver resolver = getContentResolver();
652 mDefaultLanguage = Settings.Secure.getString(resolver, TTS_DEFAULT_LANG);
Charles Chen681d0b82010-04-12 12:06:30 -0700653 mDefaultCountry = Settings.Secure.getString(resolver, TTS_DEFAULT_COUNTRY);
654 mDefaultLocVariant = Settings.Secure.getString(resolver, TTS_DEFAULT_VARIANT);
Jean-Michel Trivi44fbbea2009-07-06 14:04:54 -0700655
Jean-Michel Trivie8e23db2009-09-02 15:15:33 -0700656 // update the demo string
657 mDemoStringIndex = mDefaultLocPref.findIndexOfValue(mDefaultLanguage + LOCALE_DELIMITER
658 + mDefaultCountry);
Charles Chen8a37e612010-02-04 15:52:30 -0800659 if (mDemoStringIndex > -1){
660 mDefaultLocPref.setValueIndex(mDemoStringIndex);
661 }
Jean-Michel Trivie8e23db2009-09-02 15:15:33 -0700662 }
663
664 /**
665 * (helper function for initDefaultLang() )
666 * Returns whether there is a default language in the TTS settings.
667 */
668 private boolean hasLangPref() {
Jean-Baptiste Queru6e61b212010-04-14 10:40:48 -0700669 ContentResolver resolver = getContentResolver();
670 String language = Settings.Secure.getString(resolver, TTS_DEFAULT_LANG);
671 if ((language == null) || (language.length() < 1)) {
672 return false;
673 }
674 String country = Settings.Secure.getString(resolver, TTS_DEFAULT_COUNTRY);
675 if (country == null) {
676 return false;
677 }
678 String variant = Settings.Secure.getString(resolver, TTS_DEFAULT_VARIANT);
679 if (variant == null) {
680 return false;
681 }
682 return true;
Jean-Michel Trivie8e23db2009-09-02 15:15:33 -0700683 }
684
685 /**
686 * (helper function for initDefaultLang() )
687 * Returns whether the current Locale is supported by this Settings screen
688 */
689 private boolean isCurrentLocSupported() {
690 String currentLocID = Locale.getDefault().getISO3Language() + LOCALE_DELIMITER
691 + Locale.getDefault().getISO3Country();
692 return (mDefaultLocPref.findIndexOfValue(currentLocID) > -1);
693 }
694
695 /**
696 * (helper function for initDefaultLang() )
697 * Sets the default language in TTS settings to be the current Locale.
698 * This should only be used after checking that the current Locale is supported.
699 */
700 private void useCurrentLocAsDefault() {
701 Locale currentLocale = Locale.getDefault();
702 ContentResolver resolver = getContentResolver();
703 Settings.Secure.putString(resolver, TTS_DEFAULT_LANG, currentLocale.getISO3Language());
704 Settings.Secure.putString(resolver, TTS_DEFAULT_COUNTRY, currentLocale.getISO3Country());
705 Settings.Secure.putString(resolver, TTS_DEFAULT_VARIANT, currentLocale.getVariant());
706 }
707
708 /**
709 * (helper function for initDefaultLang() )
710 * Sets the default language in TTS settings to be one known to be supported
711 */
712 private void useSupportedLocAsDefault() {
713 ContentResolver resolver = getContentResolver();
714 Settings.Secure.putString(resolver, TTS_DEFAULT_LANG, DEFAULT_LANG_VAL);
715 Settings.Secure.putString(resolver, TTS_DEFAULT_COUNTRY, DEFAULT_COUNTRY_VAL);
716 Settings.Secure.putString(resolver, TTS_DEFAULT_VARIANT, DEFAULT_VARIANT_VAL);
Jean-Michel Trivi44fbbea2009-07-06 14:04:54 -0700717 }
718
Charles Chen5dbc74a2009-12-07 12:08:13 -0800719
Charles Chen0a0eb5f2010-03-16 20:09:17 -0700720 private void loadEngines() {
Charles Chen8c8185b2010-04-08 16:51:35 -0700721 mDefaultSynthPref = (ListPreference) findPreference(KEY_TTS_DEFAULT_SYNTH);
Charles Chen5dbc74a2009-12-07 12:08:13 -0800722
Charles Chen0a0eb5f2010-03-16 20:09:17 -0700723 // TODO (clchen): Try to see if it is possible to be more efficient here
724 // and not search for plugins again.
725 Intent intent = new Intent("android.intent.action.START_TTS_ENGINE");
726 ResolveInfo[] enginesArray = new ResolveInfo[0];
727 PackageManager pm = getPackageManager();
728 enginesArray = pm.queryIntentActivities(intent, 0).toArray(enginesArray);
729 ArrayList<CharSequence> entries = new ArrayList<CharSequence>();
730 ArrayList<CharSequence> values = new ArrayList<CharSequence>();
Charles Chenf47cce02010-03-17 17:33:23 -0700731 String enabledEngines = "";
Charles Chen0a0eb5f2010-03-16 20:09:17 -0700732 for (int i = 0; i < enginesArray.length; i++) {
Charles Chenf47cce02010-03-17 17:33:23 -0700733 String pluginPackageName = enginesArray[i].activityInfo.packageName;
734 if (pluginPackageName.equals(SYSTEM_TTS)) {
Charles Chen0a0eb5f2010-03-16 20:09:17 -0700735 entries.add(enginesArray[i].loadLabel(pm));
Charles Chenf47cce02010-03-17 17:33:23 -0700736 values.add(pluginPackageName);
Charles Chen0a0eb5f2010-03-16 20:09:17 -0700737 } else {
738 CheckBoxPreference pref = (CheckBoxPreference) findPreference(
Charles Chenf47cce02010-03-17 17:33:23 -0700739 KEY_PLUGIN_ENABLED_PREFIX + pluginPackageName);
Charles Chen0a0eb5f2010-03-16 20:09:17 -0700740 if ((pref != null) && pref.isChecked()){
741 entries.add(enginesArray[i].loadLabel(pm));
Charles Chenf47cce02010-03-17 17:33:23 -0700742 values.add(pluginPackageName);
743 enabledEngines = enabledEngines + pluginPackageName + " ";
Charles Chen0a0eb5f2010-03-16 20:09:17 -0700744 }
745 }
746 }
Charles Chenf47cce02010-03-17 17:33:23 -0700747 ContentResolver resolver = getContentResolver();
748 Settings.Secure.putString(resolver, TTS_ENABLED_PLUGINS, enabledEngines);
Charles Chen5dbc74a2009-12-07 12:08:13 -0800749
Charles Chen0a0eb5f2010-03-16 20:09:17 -0700750 CharSequence entriesArray[] = new CharSequence[entries.size()];
751 CharSequence valuesArray[] = new CharSequence[values.size()];
752
Charles Chen8c8185b2010-04-08 16:51:35 -0700753 mDefaultSynthPref.setEntries(entries.toArray(entriesArray));
754 mDefaultSynthPref.setEntryValues(values.toArray(valuesArray));
Charles Chenbe6e8272010-03-22 16:06:05 -0700755
756 // Set the selected engine based on the saved preference
757 String selectedEngine = Settings.Secure.getString(getContentResolver(), TTS_DEFAULT_SYNTH);
Charles Chen8c8185b2010-04-08 16:51:35 -0700758 int selectedEngineIndex = mDefaultSynthPref.findIndexOfValue(selectedEngine);
Charles Chenbe6e8272010-03-22 16:06:05 -0700759 if (selectedEngineIndex == -1){
Charles Chen8c8185b2010-04-08 16:51:35 -0700760 selectedEngineIndex = mDefaultSynthPref.findIndexOfValue(SYSTEM_TTS);
Charles Chenbe6e8272010-03-22 16:06:05 -0700761 }
Charles Chen8c8185b2010-04-08 16:51:35 -0700762 mDefaultSynthPref.setValueIndex(selectedEngineIndex);
Charles Chen5dbc74a2009-12-07 12:08:13 -0800763 }
Charles Chen5dbc74a2009-12-07 12:08:13 -0800764
Jean-Michel Trivied29a652009-06-05 18:37:29 -0700765}