10cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath/*
20cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath * Copyright (C) 2011 The Android Open Source Project
30cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath *
40cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath * Licensed under the Apache License, Version 2.0 (the "License");
50cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath * you may not use this file except in compliance with the License.
60cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath * You may obtain a copy of the License at
70cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath *
80cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath *      http://www.apache.org/licenses/LICENSE-2.0
90cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath *
100cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath * Unless required by applicable law or agreed to in writing, software
110cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath * distributed under the License is distributed on an "AS IS" BASIS,
120cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath * See the License for the specific language governing permissions and
140cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath * limitations under the License.
150cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath */
160cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
170cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamathpackage com.android.settings.tts;
180cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
190cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamathimport static android.provider.Settings.Secure.TTS_DEFAULT_RATE;
200cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamathimport static android.provider.Settings.Secure.TTS_DEFAULT_SYNTH;
210cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
220cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamathimport com.android.settings.R;
23263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglioimport com.android.settings.SettingsActivity;
240cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamathimport com.android.settings.SettingsPreferenceFragment;
250cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamathimport com.android.settings.tts.TtsEnginePreference.RadioButtonGroupState;
260cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
270cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamathimport android.app.AlertDialog;
280cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamathimport android.content.ActivityNotFoundException;
290cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamathimport android.content.ContentResolver;
300cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamathimport android.content.Intent;
313b60858e9cc9cc38dc58209f7dc16fa51e633749Przemyslaw Szczepaniakimport android.os.AsyncTask;
320cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamathimport android.os.Bundle;
330cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamathimport android.preference.ListPreference;
340cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamathimport android.preference.Preference;
350cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamathimport android.preference.PreferenceCategory;
360cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamathimport android.provider.Settings.SettingNotFoundException;
370cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamathimport android.speech.tts.TextToSpeech;
3803b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniakimport android.speech.tts.UtteranceProgressListener;
390cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamathimport android.speech.tts.TextToSpeech.EngineInfo;
400cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamathimport android.speech.tts.TtsEngines;
410cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamathimport android.text.TextUtils;
420cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamathimport android.util.Log;
430cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamathimport android.widget.Checkable;
440cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
456ada2d5547a161578b54e7b8ca979f06b6c911ffPrzemyslaw Szczepaniakimport java.util.ArrayList;
4603b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniakimport java.util.HashMap;
470cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamathimport java.util.List;
480cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamathimport java.util.Locale;
49f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanovimport java.util.MissingResourceException;
505a98d4368188816739243243c0a6d257b61acac1Craig Mautnerimport java.util.Objects;
5103b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniakimport java.util.Set;
520cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
530cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamathpublic class TextToSpeechSettings extends SettingsPreferenceFragment implements
540cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener,
550cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        RadioButtonGroupState {
560cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
570cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    private static final String TAG = "TextToSpeechSettings";
580cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    private static final boolean DBG = false;
590cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
600cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    /** Preference key for the "play TTS example" preference. */
610cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    private static final String KEY_PLAY_EXAMPLE = "tts_play_example";
620cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
630cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    /** Preference key for the TTS rate selection dialog. */
640cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    private static final String KEY_DEFAULT_RATE = "tts_default_rate";
650cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
664c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak    /** Preference key for the TTS status field. */
674c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak    private static final String KEY_STATUS = "tts_status";
684c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak
690cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    /**
700cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     * Preference key for the engine selection preference.
710cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     */
720cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    private static final String KEY_ENGINE_PREFERENCE_SECTION =
730cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            "tts_engine_preference_section";
740cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
750cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    /**
760cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     * These look like birth years, but they aren't mine. I'm much younger than this.
770cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     */
780cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    private static final int GET_SAMPLE_TEXT = 1983;
790cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    private static final int VOICE_DATA_INTEGRITY_CHECK = 1977;
800cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
810cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    private PreferenceCategory mEnginePreferenceCategory;
820cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    private ListPreference mDefaultRatePref;
830cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    private Preference mPlayExample;
844c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak    private Preference mEngineStatus;
850cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
860cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    private int mDefaultRate = TextToSpeech.Engine.DEFAULT_RATE;
870cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
880cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    /**
890cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     * The currently selected engine.
900cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     */
910cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    private String mCurrentEngine;
920cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
930cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    /**
940cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     * The engine checkbox that is currently checked. Saves us a bit of effort
950cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     * in deducing the right one from the currently selected engine.
960cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     */
970cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    private Checkable mCurrentChecked;
980cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
990cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    /**
1000cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     * The previously selected TTS engine. Useful for rollbacks if the users
1010cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     * choice is not loaded or fails a voice integrity check.
1020cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     */
1030cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    private String mPreviousEngine;
1040cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
1050cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    private TextToSpeech mTts = null;
1060cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    private TtsEngines mEnginesHelper = null;
1070cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
1085a98d4368188816739243243c0a6d257b61acac1Craig Mautner    private String mSampleText = null;
109eb306b4c15d721c69255f02497d2bcebff0c265fPrzemyslaw Szczepaniak
110eb306b4c15d721c69255f02497d2bcebff0c265fPrzemyslaw Szczepaniak    /**
111eb306b4c15d721c69255f02497d2bcebff0c265fPrzemyslaw Szczepaniak     * Default locale used by selected TTS engine, null if not connected to any engine.
112eb306b4c15d721c69255f02497d2bcebff0c265fPrzemyslaw Szczepaniak     */
1134c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak    private Locale mCurrentDefaultLocale;
114eb306b4c15d721c69255f02497d2bcebff0c265fPrzemyslaw Szczepaniak
115eb306b4c15d721c69255f02497d2bcebff0c265fPrzemyslaw Szczepaniak    /**
116eb306b4c15d721c69255f02497d2bcebff0c265fPrzemyslaw Szczepaniak     * List of available locals of selected TTS engine, as returned by
117eb306b4c15d721c69255f02497d2bcebff0c265fPrzemyslaw Szczepaniak     * {@link TextToSpeech.Engine#ACTION_CHECK_TTS_DATA} activity. If empty, then activity
118eb306b4c15d721c69255f02497d2bcebff0c265fPrzemyslaw Szczepaniak     * was not yet called.
119eb306b4c15d721c69255f02497d2bcebff0c265fPrzemyslaw Szczepaniak     */
1206ada2d5547a161578b54e7b8ca979f06b6c911ffPrzemyslaw Szczepaniak    private List<String> mAvailableStrLocals;
1214c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak
1220cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    /**
1230cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     * The initialization listener used when we are initalizing the settings
1240cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     * screen for the first time (as opposed to when a user changes his choice
1250cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     * of engine).
1260cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     */
1270cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    private final TextToSpeech.OnInitListener mInitListener = new TextToSpeech.OnInitListener() {
1280cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        @Override
1290cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        public void onInit(int status) {
1300cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            onInitEngine(status);
1310cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        }
1320cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    };
1330cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
1340cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    /**
1350cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     * The initialization listener used when the user changes his choice of
1360cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     * engine (as opposed to when then screen is being initialized for the first
1370cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     * time).
1380cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     */
1390cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    private final TextToSpeech.OnInitListener mUpdateListener = new TextToSpeech.OnInitListener() {
1400cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        @Override
1410cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        public void onInit(int status) {
1420cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            onUpdateEngine(status);
1430cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        }
1440cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    };
1450cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
1460cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    @Override
1470cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    public void onCreate(Bundle savedInstanceState) {
1480cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        super.onCreate(savedInstanceState);
1490cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        addPreferencesFromResource(R.xml.tts_settings);
1500cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
1510cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        getActivity().setVolumeControlStream(TextToSpeech.Engine.DEFAULT_STREAM);
1520cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
1530cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        mPlayExample = findPreference(KEY_PLAY_EXAMPLE);
1540cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        mPlayExample.setOnPreferenceClickListener(this);
1550e01f128ab8a8525a4d3fd72980e468f4de1e56cPrzemyslaw Szczepaniak        mPlayExample.setEnabled(false);
1560cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
1570cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        mEnginePreferenceCategory = (PreferenceCategory) findPreference(
1580cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath                KEY_ENGINE_PREFERENCE_SECTION);
1590cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        mDefaultRatePref = (ListPreference) findPreference(KEY_DEFAULT_RATE);
1600cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
1614c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak        mEngineStatus = findPreference(KEY_STATUS);
1626ada2d5547a161578b54e7b8ca979f06b6c911ffPrzemyslaw Szczepaniak        updateEngineStatus(R.string.tts_status_checking);
1634c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak
1640cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        mTts = new TextToSpeech(getActivity().getApplicationContext(), mInitListener);
1650cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        mEnginesHelper = new TtsEngines(getActivity().getApplicationContext());
1660cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
16703b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak        setTtsUtteranceProgressListener();
1680cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        initSettings();
1693b60858e9cc9cc38dc58209f7dc16fa51e633749Przemyslaw Szczepaniak
1703b60858e9cc9cc38dc58209f7dc16fa51e633749Przemyslaw Szczepaniak        // Prevent restarting the TTS connection on rotation
1713b60858e9cc9cc38dc58209f7dc16fa51e633749Przemyslaw Szczepaniak        setRetainInstance(true);
1720cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    }
1730cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
1744c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak    @Override
1754c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak    public void onResume() {
1764c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak        super.onResume();
1774c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak
1784c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak        if (mTts == null || mCurrentDefaultLocale == null) {
1794c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak            return;
1804c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak        }
1814c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak        Locale ttsDefaultLocale = mTts.getDefaultLanguage();
1824c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak        if (mCurrentDefaultLocale != null && !mCurrentDefaultLocale.equals(ttsDefaultLocale)) {
1834c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak            updateWidgetState(false);
1844c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak            checkDefaultLocale();
1854c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak        }
1864c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak    }
1874c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak
18803b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak    private void setTtsUtteranceProgressListener() {
18903b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak        if (mTts == null) {
19003b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak            return;
19103b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak        }
19203b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak        mTts.setOnUtteranceProgressListener(new UtteranceProgressListener() {
19303b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak            @Override
19403b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak            public void onStart(String utteranceId) {}
19503b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak
19603b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak            @Override
19703b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak            public void onDone(String utteranceId) {}
19803b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak
19903b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak            @Override
20003b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak            public void onError(String utteranceId) {
20103b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak                Log.e(TAG, "Error while trying to synthesize sample text");
20203b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak            }
20303b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak        });
20403b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak    }
20503b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak
2060cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    @Override
2070cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    public void onDestroy() {
2080cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        super.onDestroy();
2090cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        if (mTts != null) {
2100cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            mTts.shutdown();
2110cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            mTts = null;
2120cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        }
2130cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    }
2140cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
2150cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    private void initSettings() {
2160cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        final ContentResolver resolver = getContentResolver();
2170cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
2180cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        // Set up the default rate.
2190cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        try {
220263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglio            mDefaultRate = android.provider.Settings.Secure.getInt(resolver, TTS_DEFAULT_RATE);
2210cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        } catch (SettingNotFoundException e) {
2220cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            // Default rate setting not found, initialize it
2230cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            mDefaultRate = TextToSpeech.Engine.DEFAULT_RATE;
2240cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        }
2250cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        mDefaultRatePref.setValue(String.valueOf(mDefaultRate));
2260cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        mDefaultRatePref.setOnPreferenceChangeListener(this);
2270cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
2280cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        mCurrentEngine = mTts.getCurrentEngine();
2290cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
230263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglio        SettingsActivity activity = null;
231263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglio        if (getActivity() instanceof SettingsActivity) {
232263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglio            activity = (SettingsActivity) getActivity();
2330cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        } else {
2340cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            throw new IllegalStateException("TextToSpeechSettings used outside a " +
235263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglio                    "Settings");
2360cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        }
2370cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
2380cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        mEnginePreferenceCategory.removeAll();
2390cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
2400cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        List<EngineInfo> engines = mEnginesHelper.getEngines();
2410cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        for (EngineInfo engine : engines) {
2420cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            TtsEnginePreference enginePref = new TtsEnginePreference(getActivity(), engine,
243263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglio                    this, activity);
2440cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            mEnginePreferenceCategory.addPreference(enginePref);
2450cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        }
2460cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
2470cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        checkVoiceData(mCurrentEngine);
2480cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    }
2490cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
2500cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    /**
2514c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak     * Called when the TTS engine is initialized.
2524c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak     */
2534c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak    public void onInitEngine(int status) {
2544c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak        if (status == TextToSpeech.SUCCESS) {
2554c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak            if (DBG) Log.d(TAG, "TTS engine for settings screen initialized.");
2564c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak            checkDefaultLocale();
2574c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak        } else {
2584c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak            if (DBG) Log.d(TAG, "TTS engine for settings screen failed to initialize successfully.");
2594c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak            updateWidgetState(false);
2604c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak        }
2614c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak    }
2624c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak
2634c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak    private void checkDefaultLocale() {
2644c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak        Locale defaultLocale = mTts.getDefaultLanguage();
2654c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak        if (defaultLocale == null) {
2664c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak            Log.e(TAG, "Failed to get default language from engine " + mCurrentEngine);
2674c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak            updateWidgetState(false);
2684c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak            updateEngineStatus(R.string.tts_status_not_supported);
2694c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak            return;
2704c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak        }
2714c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak
2726ac8ddb8983a4abdf37214c86394033d6bc79235Przemyslaw Szczepaniak        // ISO-3166 alpha 3 country codes are out of spec. If we won't normalize,
2736ac8ddb8983a4abdf37214c86394033d6bc79235Przemyslaw Szczepaniak        // we may end up with English (USA)and German (DEU).
2745a98d4368188816739243243c0a6d257b61acac1Craig Mautner        final Locale oldDefaultLocale = mCurrentDefaultLocale;
2756ac8ddb8983a4abdf37214c86394033d6bc79235Przemyslaw Szczepaniak        mCurrentDefaultLocale = mEnginesHelper.parseLocaleString(defaultLocale.toString());
2765a98d4368188816739243243c0a6d257b61acac1Craig Mautner        if (!Objects.equals(oldDefaultLocale, mCurrentDefaultLocale)) {
2775a98d4368188816739243243c0a6d257b61acac1Craig Mautner            mSampleText = null;
2785a98d4368188816739243243c0a6d257b61acac1Craig Mautner        }
2794c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak
2804c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak        int defaultAvailable = mTts.setLanguage(defaultLocale);
2815a98d4368188816739243243c0a6d257b61acac1Craig Mautner        if (evaluateDefaultLocale() && mSampleText == null) {
2826ada2d5547a161578b54e7b8ca979f06b6c911ffPrzemyslaw Szczepaniak            getSampleText();
2836ada2d5547a161578b54e7b8ca979f06b6c911ffPrzemyslaw Szczepaniak        }
2846ada2d5547a161578b54e7b8ca979f06b6c911ffPrzemyslaw Szczepaniak    }
2856ada2d5547a161578b54e7b8ca979f06b6c911ffPrzemyslaw Szczepaniak
2866ada2d5547a161578b54e7b8ca979f06b6c911ffPrzemyslaw Szczepaniak    private boolean evaluateDefaultLocale() {
287eb306b4c15d721c69255f02497d2bcebff0c265fPrzemyslaw Szczepaniak        // Check if we are connected to the engine, and CHECK_VOICE_DATA returned list
288eb306b4c15d721c69255f02497d2bcebff0c265fPrzemyslaw Szczepaniak        // of available languages.
289eb306b4c15d721c69255f02497d2bcebff0c265fPrzemyslaw Szczepaniak        if (mCurrentDefaultLocale == null || mAvailableStrLocals == null) {
2906ada2d5547a161578b54e7b8ca979f06b6c911ffPrzemyslaw Szczepaniak            return false;
2916ada2d5547a161578b54e7b8ca979f06b6c911ffPrzemyslaw Szczepaniak        }
2926ada2d5547a161578b54e7b8ca979f06b6c911ffPrzemyslaw Szczepaniak
2936ada2d5547a161578b54e7b8ca979f06b6c911ffPrzemyslaw Szczepaniak        boolean notInAvailableLangauges = true;
294f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov        try {
295f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov            // Check if language is listed in CheckVoices Action result as available voice.
296f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov            String defaultLocaleStr = mCurrentDefaultLocale.getISO3Language();
297f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov            if (!TextUtils.isEmpty(mCurrentDefaultLocale.getISO3Country())) {
298f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov                defaultLocaleStr += "-" + mCurrentDefaultLocale.getISO3Country();
299f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov            }
300f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov            if (!TextUtils.isEmpty(mCurrentDefaultLocale.getVariant())) {
301f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov                defaultLocaleStr += "-" + mCurrentDefaultLocale.getVariant();
302f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov            }
303eb306b4c15d721c69255f02497d2bcebff0c265fPrzemyslaw Szczepaniak
304f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov            for (String loc : mAvailableStrLocals) {
305f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov                if (loc.equalsIgnoreCase(defaultLocaleStr)) {
306f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov                  notInAvailableLangauges = false;
307f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov                  break;
308f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov                }
3096ada2d5547a161578b54e7b8ca979f06b6c911ffPrzemyslaw Szczepaniak            }
310f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov        } catch (MissingResourceException e) {
311f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov            if (DBG) Log.wtf(TAG, "MissingResourceException", e);
312f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov            updateEngineStatus(R.string.tts_status_not_supported);
313f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov            updateWidgetState(false);
314f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov            return false;
3156ada2d5547a161578b54e7b8ca979f06b6c911ffPrzemyslaw Szczepaniak        }
3166ada2d5547a161578b54e7b8ca979f06b6c911ffPrzemyslaw Szczepaniak
317f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov        int defaultAvailable = mTts.setLanguage(mCurrentDefaultLocale);
3186ada2d5547a161578b54e7b8ca979f06b6c911ffPrzemyslaw Szczepaniak        if (defaultAvailable == TextToSpeech.LANG_NOT_SUPPORTED ||
3196ada2d5547a161578b54e7b8ca979f06b6c911ffPrzemyslaw Szczepaniak                defaultAvailable == TextToSpeech.LANG_MISSING_DATA ||
320eb306b4c15d721c69255f02497d2bcebff0c265fPrzemyslaw Szczepaniak                notInAvailableLangauges) {
3214c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak            if (DBG) Log.d(TAG, "Default locale for this TTS engine is not supported.");
3224c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak            updateEngineStatus(R.string.tts_status_not_supported);
3236ada2d5547a161578b54e7b8ca979f06b6c911ffPrzemyslaw Szczepaniak            updateWidgetState(false);
3246ada2d5547a161578b54e7b8ca979f06b6c911ffPrzemyslaw Szczepaniak            return false;
3254c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak        } else {
3264c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak            if (isNetworkRequiredForSynthesis()) {
3274c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak                updateEngineStatus(R.string.tts_status_requires_network);
3284c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak            } else {
3294c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak                updateEngineStatus(R.string.tts_status_ok);
3304c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak            }
3316ada2d5547a161578b54e7b8ca979f06b6c911ffPrzemyslaw Szczepaniak            updateWidgetState(true);
3326ada2d5547a161578b54e7b8ca979f06b6c911ffPrzemyslaw Szczepaniak            return true;
3334c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak        }
3344c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak    }
3354c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak
3364c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak    /**
3370cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     * Ask the current default engine to return a string of sample text to be
3380cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     * spoken to the user.
3390cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     */
3400cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    private void getSampleText() {
3410cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        String currentEngine = mTts.getCurrentEngine();
3420cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
3430cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        if (TextUtils.isEmpty(currentEngine)) currentEngine = mTts.getDefaultEngine();
3440cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
3450cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        // TODO: This is currently a hidden private API. The intent extras
3460cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        // and the intent action should be made public if we intend to make this
3470cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        // a public API. We fall back to using a canned set of strings if this
3480cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        // doesn't work.
3490cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        Intent intent = new Intent(TextToSpeech.Engine.ACTION_GET_SAMPLE_TEXT);
3500cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
3514c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak        intent.putExtra("language", mCurrentDefaultLocale.getLanguage());
3524c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak        intent.putExtra("country", mCurrentDefaultLocale.getCountry());
3534c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak        intent.putExtra("variant", mCurrentDefaultLocale.getVariant());
3540cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        intent.setPackage(currentEngine);
3550cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
3560cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        try {
3570cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            if (DBG) Log.d(TAG, "Getting sample text: " + intent.toUri(0));
3580cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            startActivityForResult(intent, GET_SAMPLE_TEXT);
3590cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        } catch (ActivityNotFoundException ex) {
3600cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            Log.e(TAG, "Failed to get sample text, no activity found for " + intent + ")");
3610cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        }
3620cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    }
3630cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
3640cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    /**
3650cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     * Called when voice data integrity check returns
3660cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     */
3670cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    @Override
3680cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    public void onActivityResult(int requestCode, int resultCode, Intent data) {
3690cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        if (requestCode == GET_SAMPLE_TEXT) {
3700cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            onSampleTextReceived(resultCode, data);
3710cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        } else if (requestCode == VOICE_DATA_INTEGRITY_CHECK) {
3720cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            onVoiceDataIntegrityCheckDone(data);
3730cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        }
3740cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    }
3750cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
3760cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    private String getDefaultSampleString() {
3770cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        if (mTts != null && mTts.getLanguage() != null) {
378f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov            try {
379f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov                final String currentLang = mTts.getLanguage().getISO3Language();
380f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov                String[] strings = getActivity().getResources().getStringArray(
381f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov                        R.array.tts_demo_strings);
382f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov                String[] langs = getActivity().getResources().getStringArray(
383f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov                        R.array.tts_demo_string_langs);
384f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov
385f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov                for (int i = 0; i < strings.length; ++i) {
386f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov                    if (langs[i].equals(currentLang)) {
387f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov                        return strings[i];
388f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov                    }
3890cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath                }
390f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov            } catch (MissingResourceException e) {
391f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov                if (DBG) Log.wtf(TAG, "MissingResourceException", e);
392f365216391a8f3f71a988b79863bbcde9197fc7cShuhrat Dehkanov                // Ignore and fall back to default sample string
3930cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            }
3940cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        }
3954c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak        return getString(R.string.tts_default_sample_string);
3960cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    }
3970cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
39803b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak    private boolean isNetworkRequiredForSynthesis() {
3994c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak        Set<String> features = mTts.getFeatures(mCurrentDefaultLocale);
4000e01f128ab8a8525a4d3fd72980e468f4de1e56cPrzemyslaw Szczepaniak        if (features == null) {
4010e01f128ab8a8525a4d3fd72980e468f4de1e56cPrzemyslaw Szczepaniak          return false;
4020e01f128ab8a8525a4d3fd72980e468f4de1e56cPrzemyslaw Szczepaniak        }
40303b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak        return features.contains(TextToSpeech.Engine.KEY_FEATURE_NETWORK_SYNTHESIS) &&
40403b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak                !features.contains(TextToSpeech.Engine.KEY_FEATURE_EMBEDDED_SYNTHESIS);
40503b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak    }
40603b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak
4070cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    private void onSampleTextReceived(int resultCode, Intent data) {
4080cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        String sample = getDefaultSampleString();
4090cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
4100cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        if (resultCode == TextToSpeech.LANG_AVAILABLE && data != null) {
4110cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            if (data != null && data.getStringExtra("sampleText") != null) {
4120cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath                sample = data.getStringExtra("sampleText");
4130cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            }
4140cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            if (DBG) Log.d(TAG, "Got sample text: " + sample);
4150cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        } else {
4160cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            if (DBG) Log.d(TAG, "Using default sample text :" + sample);
4170cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        }
4180cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
4194c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak        mSampleText = sample;
4204c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak        if (mSampleText != null) {
4214c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak            updateWidgetState(true);
4224c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak        } else {
4234c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak            Log.e(TAG, "Did not have a sample string for the requested language. Using default");
4244c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak        }
4254c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak    }
42603b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak
4274c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak    private void speakSampleText() {
4284c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak        final boolean networkRequired = isNetworkRequiredForSynthesis();
4294c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak        if (!networkRequired || networkRequired &&
4304c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak                (mTts.isLanguageAvailable(mCurrentDefaultLocale) >= TextToSpeech.LANG_AVAILABLE)) {
4314c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak            HashMap<String, String> params = new HashMap<String, String>();
4324c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak            params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "Sample");
43303b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak
4344c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak            mTts.speak(mSampleText, TextToSpeech.QUEUE_FLUSH, params);
4350cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        } else {
4364c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak            Log.w(TAG, "Network required for sample synthesis for requested language");
4374c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak            displayNetworkAlert();
4380cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        }
4390cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    }
4400cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
441923187a159cb0c192a2f978a6bf1dd51275ea916Przemyslaw Szczepaniak    @Override
4420cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    public boolean onPreferenceChange(Preference preference, Object objValue) {
4430cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        if (KEY_DEFAULT_RATE.equals(preference.getKey())) {
4440cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            // Default rate
4450cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            mDefaultRate = Integer.parseInt((String) objValue);
4460cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            try {
447263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglio                android.provider.Settings.Secure.putInt(getContentResolver(),
448263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglio                        TTS_DEFAULT_RATE, mDefaultRate);
4490cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath                if (mTts != null) {
4500cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath                    mTts.setSpeechRate(mDefaultRate / 100.0f);
4510cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath                }
4520cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath                if (DBG) Log.d(TAG, "TTS default rate changed, now " + mDefaultRate);
4530cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            } catch (NumberFormatException e) {
4540cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath                Log.e(TAG, "could not persist default TTS rate setting", e);
4550cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            }
4560cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        }
4570cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
4580cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        return true;
4590cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    }
4600cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
4610cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    /**
4620cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     * Called when mPlayExample is clicked
4630cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     */
464923187a159cb0c192a2f978a6bf1dd51275ea916Przemyslaw Szczepaniak    @Override
4650cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    public boolean onPreferenceClick(Preference preference) {
4660cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        if (preference == mPlayExample) {
4670cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            // Get the sample text from the TTS engine; onActivityResult will do
4680cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            // the actual speaking
4694c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak            speakSampleText();
4700cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            return true;
4710cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        }
4720cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
4730cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        return false;
4740cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    }
4750cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
4760cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    private void updateWidgetState(boolean enable) {
4770cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        mPlayExample.setEnabled(enable);
4780cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        mDefaultRatePref.setEnabled(enable);
4794c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak        mEngineStatus.setEnabled(enable);
4804c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak    }
4814c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak
4824c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak    private void updateEngineStatus(int resourceId) {
4834c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak        Locale locale = mCurrentDefaultLocale;
4844c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak        if (locale == null) {
4854c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak            locale = Locale.getDefault();
4864c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak        }
4874c85c1d6f4e97f33e03a8f28f882d7a4110b8f88Przemyslaw Szczepaniak        mEngineStatus.setSummary(getString(resourceId, locale.getDisplayName()));
4880cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    }
4890cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
49003b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak    private void displayNetworkAlert() {
49103b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
4926bfec2d6b197068dd355bd1742179fe3da07136fAlan Viverette        builder.setTitle(android.R.string.dialog_alert_title)
4936bfec2d6b197068dd355bd1742179fe3da07136fAlan Viverette                .setMessage(getActivity().getString(R.string.tts_engine_network_required))
4946bfec2d6b197068dd355bd1742179fe3da07136fAlan Viverette                .setCancelable(false)
4956bfec2d6b197068dd355bd1742179fe3da07136fAlan Viverette                .setPositiveButton(android.R.string.ok, null);
49603b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak
49703b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak        AlertDialog dialog = builder.create();
49803b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak        dialog.show();
49903b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak    }
50003b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak
5010cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    private void updateDefaultEngine(String engine) {
5020cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        if (DBG) Log.d(TAG, "Updating default synth to : " + engine);
5030cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
5040cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        // Disable the "play sample text" preference and the speech
5050cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        // rate preference while the engine is being swapped.
5060cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        updateWidgetState(false);
5076ada2d5547a161578b54e7b8ca979f06b6c911ffPrzemyslaw Szczepaniak        updateEngineStatus(R.string.tts_status_checking);
5080cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
5090cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        // Keep track of the previous engine that was being used. So that
5100cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        // we can reuse the previous engine.
5110cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        //
5120cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        // Note that if TextToSpeech#getCurrentEngine is not null, it means at
5130cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        // the very least that we successfully bound to the engine service.
5140cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        mPreviousEngine = mTts.getCurrentEngine();
5150cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
5160cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        // Step 1: Shut down the existing TTS engine.
5170cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        if (mTts != null) {
5180cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            try {
5190cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath                mTts.shutdown();
5200cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath                mTts = null;
5210cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            } catch (Exception e) {
5220cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath                Log.e(TAG, "Error shutting down TTS engine" + e);
5230cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            }
5240cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        }
5250cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
5260cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        // Step 2: Connect to the new TTS engine.
5270cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        // Step 3 is continued on #onUpdateEngine (below) which is called when
5280cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        // the app binds successfully to the engine.
5290cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        if (DBG) Log.d(TAG, "Updating engine : Attempting to connect to engine: " + engine);
5300cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        mTts = new TextToSpeech(getActivity().getApplicationContext(), mUpdateListener, engine);
53103b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak        setTtsUtteranceProgressListener();
5320cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    }
5330cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
5340cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    /*
5350cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     * Step 3: We have now bound to the TTS engine the user requested. We will
5360cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     * attempt to check voice data for the engine if we successfully bound to it,
5370cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     * or revert to the previous engine if we didn't.
5380cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     */
5390cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    public void onUpdateEngine(int status) {
5400cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        if (status == TextToSpeech.SUCCESS) {
5410cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            if (DBG) {
5420cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath                Log.d(TAG, "Updating engine: Successfully bound to the engine: " +
5430cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath                        mTts.getCurrentEngine());
5440cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            }
5450cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            checkVoiceData(mTts.getCurrentEngine());
5460cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        } else {
5470cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            if (DBG) Log.d(TAG, "Updating engine: Failed to bind to engine, reverting.");
5480cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            if (mPreviousEngine != null) {
5490cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath                // This is guaranteed to at least bind, since mPreviousEngine would be
5500cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath                // null if the previous bind to this engine failed.
5510cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath                mTts = new TextToSpeech(getActivity().getApplicationContext(), mInitListener,
5520cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath                        mPreviousEngine);
55303b9f86722fbda98d1f4978466b5f4f0cb327161Przemyslaw Szczepaniak                setTtsUtteranceProgressListener();
5540cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            }
5550cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            mPreviousEngine = null;
5560cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        }
5570cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    }
5580cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
5590cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    /*
5600cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     * Step 4: Check whether the voice data for the engine is ok.
5610cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     */
5620cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    private void checkVoiceData(String engine) {
5630cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        Intent intent = new Intent(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
5640cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        intent.setPackage(engine);
5650cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        try {
5660cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            if (DBG) Log.d(TAG, "Updating engine: Checking voice data: " + intent.toUri(0));
5670cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            startActivityForResult(intent, VOICE_DATA_INTEGRITY_CHECK);
5680cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        } catch (ActivityNotFoundException ex) {
5690cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            Log.e(TAG, "Failed to check TTS data, no activity found for " + intent + ")");
5700cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        }
5710cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    }
5720cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
5730cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    /*
5740cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     * Step 5: The voice data check is complete.
5750cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath     */
5760cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    private void onVoiceDataIntegrityCheckDone(Intent data) {
5770cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        final String engine = mTts.getCurrentEngine();
5780cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
5790cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        if (engine == null) {
5800cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            Log.e(TAG, "Voice data check complete, but no engine bound");
5810cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            return;
5820cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        }
5830cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
5840cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        if (data == null){
5850cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            Log.e(TAG, "Engine failed voice data integrity check (null return)" +
5860cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath                    mTts.getCurrentEngine());
5870cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            return;
5880cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        }
5890cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
590263bcc8b732dbb47d3ce63904e0e05191fabbad6Fabrice Di Meglio        android.provider.Settings.Secure.putString(getContentResolver(), TTS_DEFAULT_SYNTH, engine);
5910cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
5926ada2d5547a161578b54e7b8ca979f06b6c911ffPrzemyslaw Szczepaniak        mAvailableStrLocals = data.getStringArrayListExtra(
593eb306b4c15d721c69255f02497d2bcebff0c265fPrzemyslaw Szczepaniak            TextToSpeech.Engine.EXTRA_AVAILABLE_VOICES);
594eb306b4c15d721c69255f02497d2bcebff0c265fPrzemyslaw Szczepaniak        if (mAvailableStrLocals == null) {
595eb306b4c15d721c69255f02497d2bcebff0c265fPrzemyslaw Szczepaniak            Log.e(TAG, "Voice data check complete, but no available voices found");
596eb306b4c15d721c69255f02497d2bcebff0c265fPrzemyslaw Szczepaniak            // Set mAvailableStrLocals to empty list
597eb306b4c15d721c69255f02497d2bcebff0c265fPrzemyslaw Szczepaniak            mAvailableStrLocals = new ArrayList<String>();
598eb306b4c15d721c69255f02497d2bcebff0c265fPrzemyslaw Szczepaniak        }
599eb306b4c15d721c69255f02497d2bcebff0c265fPrzemyslaw Szczepaniak        if (evaluateDefaultLocale()) {
600eb306b4c15d721c69255f02497d2bcebff0c265fPrzemyslaw Szczepaniak            getSampleText();
601eb306b4c15d721c69255f02497d2bcebff0c265fPrzemyslaw Szczepaniak        }
6026ada2d5547a161578b54e7b8ca979f06b6c911ffPrzemyslaw Szczepaniak
6030cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        final int engineCount = mEnginePreferenceCategory.getPreferenceCount();
6040cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        for (int i = 0; i < engineCount; ++i) {
6050cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            final Preference p = mEnginePreferenceCategory.getPreference(i);
6060cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            if (p instanceof TtsEnginePreference) {
6070cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath                TtsEnginePreference enginePref = (TtsEnginePreference) p;
6080cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath                if (enginePref.getKey().equals(engine)) {
6090cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath                    enginePref.setVoiceDataDetails(data);
6100cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath                    break;
6110cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath                }
6120cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath            }
6130cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        }
6140cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    }
6150cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
6160cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    @Override
6170cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    public Checkable getCurrentChecked() {
6180cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        return mCurrentChecked;
6190cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    }
6200cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
6210cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    @Override
6220cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    public String getCurrentKey() {
6230cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        return mCurrentEngine;
6240cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    }
6250cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
6260cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    @Override
6270cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    public void setCurrentChecked(Checkable current) {
6280cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        mCurrentChecked = current;
6290cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    }
6300cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
6310cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    @Override
6320cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    public void setCurrentKey(String key) {
6330cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath        mCurrentEngine = key;
634820dc4c910e81fb8576dfcca2d64632f81c402b0Przemyslaw Szczepaniak        updateDefaultEngine(mCurrentEngine);
6350cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath    }
6360cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath
6370cfbb0f10aca100795169891c9a152d56390a3cfNarayan Kamath}
638