1 /* 2 * Copyright (C) 2011 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 17 package com.android.settings.tts; 18 19 import com.android.settings.R; 20 import com.android.settings.SettingsPreferenceFragment; 21 22 import android.content.ActivityNotFoundException; 23 import android.content.Intent; 24 import android.os.Bundle; 25 import android.preference.ListPreference; 26 import android.preference.Preference; 27 import android.preference.Preference.OnPreferenceChangeListener; 28 import android.preference.Preference.OnPreferenceClickListener; 29 import android.preference.PreferenceScreen; 30 import android.speech.tts.TextToSpeech; 31 import android.speech.tts.TtsEngines; 32 import android.text.TextUtils; 33 import android.util.Log; 34 35 import java.util.ArrayList; 36 import java.util.Locale; 37 38 39 public class TtsEngineSettingsFragment extends SettingsPreferenceFragment implements 40 OnPreferenceClickListener, OnPreferenceChangeListener { 41 private static final String TAG = "TtsEngineSettings"; 42 private static final boolean DBG = false; 43 44 private static final String KEY_ENGINE_LOCALE = "tts_default_lang"; 45 private static final String KEY_ENGINE_SETTINGS = "tts_engine_settings"; 46 private static final String KEY_INSTALL_DATA = "tts_install_data"; 47 48 private TtsEngines mEnginesHelper; 49 private ListPreference mLocalePreference; 50 private Preference mEngineSettingsPreference; 51 private Preference mInstallVoicesPreference; 52 private Intent mEngineSettingsIntent; 53 54 public TtsEngineSettingsFragment() { 55 super(); 56 } 57 58 @Override 59 public void onCreate(Bundle savedInstanceState) { 60 super.onCreate(savedInstanceState); 61 addPreferencesFromResource(R.xml.tts_engine_settings); 62 mEnginesHelper = new TtsEngines(getActivity()); 63 64 final PreferenceScreen root = getPreferenceScreen(); 65 mLocalePreference = (ListPreference) root.findPreference(KEY_ENGINE_LOCALE); 66 mLocalePreference.setOnPreferenceChangeListener(this); 67 mEngineSettingsPreference = root.findPreference(KEY_ENGINE_SETTINGS); 68 mEngineSettingsPreference.setOnPreferenceClickListener(this); 69 mInstallVoicesPreference = root.findPreference(KEY_INSTALL_DATA); 70 mInstallVoicesPreference.setOnPreferenceClickListener(this); 71 72 root.setTitle(getEngineLabel()); 73 root.setKey(getEngineName()); 74 mEngineSettingsPreference.setTitle(getResources().getString( 75 R.string.tts_engine_settings_title, getEngineLabel())); 76 77 mEngineSettingsIntent = mEnginesHelper.getSettingsIntent(getEngineName()); 78 if (mEngineSettingsIntent == null) { 79 mEngineSettingsPreference.setEnabled(false); 80 } 81 mInstallVoicesPreference.setEnabled(false); 82 83 updateVoiceDetails(); 84 } 85 86 private void updateVoiceDetails() { 87 final Intent voiceDataDetails = getArguments().getParcelable( 88 TtsEnginePreference.FRAGMENT_ARGS_VOICES); 89 if (DBG) Log.d(TAG, "Parsing voice data details, data: " + voiceDataDetails.toUri(0)); 90 ArrayList<String> available = voiceDataDetails.getStringArrayListExtra( 91 TextToSpeech.Engine.EXTRA_AVAILABLE_VOICES); 92 ArrayList<String> unavailable = voiceDataDetails.getStringArrayListExtra( 93 TextToSpeech.Engine.EXTRA_UNAVAILABLE_VOICES); 94 95 if (available == null || unavailable == null){ 96 Log.e(TAG, "TTS data check failed (available == null)."); 97 return; 98 } 99 100 if (unavailable.size() > 0) { 101 mInstallVoicesPreference.setEnabled(true); 102 } 103 104 if (available.size() > 0) { 105 updateDefaultLocalePref(available); 106 } else { 107 final CharSequence[] empty = new CharSequence[0]; 108 mLocalePreference.setEntries(empty); 109 mLocalePreference.setEntryValues(empty); 110 } 111 } 112 113 private void updateDefaultLocalePref(ArrayList<String> availableLangs) { 114 String currentLocale = mEnginesHelper.getLocalePrefForEngine( 115 getEngineName()); 116 117 CharSequence[] entries = new CharSequence[availableLangs.size()]; 118 CharSequence[] entryValues = new CharSequence[availableLangs.size()]; 119 120 int selectedLanguageIndex = -1; 121 for (int i = 0; i < availableLangs.size(); i++) { 122 String[] langCountryVariant = availableLangs.get(i).split("-"); 123 Locale loc = null; 124 if (langCountryVariant.length == 1){ 125 loc = new Locale(langCountryVariant[0]); 126 } else if (langCountryVariant.length == 2){ 127 loc = new Locale(langCountryVariant[0], langCountryVariant[1]); 128 } else if (langCountryVariant.length == 3){ 129 loc = new Locale(langCountryVariant[0], langCountryVariant[1], 130 langCountryVariant[2]); 131 } 132 if (loc != null){ 133 entries[i] = loc.getDisplayName(); 134 entryValues[i] = availableLangs.get(i); 135 if (entryValues[i].equals(currentLocale)) { 136 selectedLanguageIndex = i; 137 } 138 } 139 } 140 141 mLocalePreference.setEntries(entries); 142 mLocalePreference.setEntryValues(entryValues); 143 if (selectedLanguageIndex > -1) { 144 mLocalePreference.setValueIndex(selectedLanguageIndex); 145 } else { 146 mLocalePreference.setValueIndex(0); 147 mEnginesHelper.updateLocalePrefForEngine(getEngineName(), 148 availableLangs.get(0)); 149 } 150 } 151 152 /** 153 * Ask the current default engine to launch the matching INSTALL_TTS_DATA activity 154 * so the required TTS files are properly installed. 155 */ 156 private void installVoiceData() { 157 if (TextUtils.isEmpty(getEngineName())) return; 158 Intent intent = new Intent(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA); 159 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 160 intent.setPackage(getEngineName()); 161 try { 162 Log.v(TAG, "Installing voice data: " + intent.toUri(0)); 163 startActivity(intent); 164 } catch (ActivityNotFoundException ex) { 165 Log.e(TAG, "Failed to install TTS data, no acitivty found for " + intent + ")"); 166 } 167 } 168 169 @Override 170 public boolean onPreferenceClick(Preference preference) { 171 if (preference == mInstallVoicesPreference) { 172 installVoiceData(); 173 return true; 174 } else if (preference == mEngineSettingsPreference) { 175 startActivity(mEngineSettingsIntent); 176 return true; 177 } 178 179 return false; 180 } 181 182 @Override 183 public boolean onPreferenceChange(Preference preference, Object newValue) { 184 if (preference == mLocalePreference) { 185 mEnginesHelper.updateLocalePrefForEngine(getEngineName(), (String) newValue); 186 return true; 187 } 188 189 return false; 190 } 191 192 private String getEngineName() { 193 return getArguments().getString(TtsEnginePreference.FRAGMENT_ARGS_NAME); 194 } 195 196 private String getEngineLabel() { 197 return getArguments().getString(TtsEnginePreference.FRAGMENT_ARGS_LABEL); 198 } 199 200 } 201