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 android.app.AlertDialog; 20 import android.content.Context; 21 import android.content.DialogInterface; 22 import android.content.Intent; 23 import android.speech.tts.TextToSpeech.EngineInfo; 24 import android.support.v7.preference.Preference; 25 import android.support.v7.preference.PreferenceViewHolder; 26 import android.util.Log; 27 import android.widget.Checkable; 28 import android.widget.CompoundButton; 29 import android.widget.RadioButton; 30 31 import com.android.settings.R; 32 import com.android.settings.SettingsActivity; 33 34 35 public class TtsEnginePreference extends Preference { 36 37 private static final String TAG = "TtsEnginePreference"; 38 39 /** 40 * The engine information for the engine this preference represents. 41 * Contains it's name, label etc. which are used for display. 42 */ 43 private final EngineInfo mEngineInfo; 44 45 /** 46 * The shared radio button state, which button is checked etc. 47 */ 48 private final RadioButtonGroupState mSharedState; 49 50 /** 51 * When true, the change callbacks on the radio button will not 52 * fire. 53 */ 54 private volatile boolean mPreventRadioButtonCallbacks; 55 56 private RadioButton mRadioButton; 57 private Intent mVoiceCheckData; 58 59 private final CompoundButton.OnCheckedChangeListener mRadioChangeListener = 60 new CompoundButton.OnCheckedChangeListener() { 61 @Override 62 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 63 onRadioButtonClicked(buttonView, isChecked); 64 } 65 }; 66 TtsEnginePreference(Context context, EngineInfo info, RadioButtonGroupState state, SettingsActivity prefActivity)67 public TtsEnginePreference(Context context, EngineInfo info, RadioButtonGroupState state, 68 SettingsActivity prefActivity) { 69 super(context); 70 setLayoutResource(R.layout.preference_tts_engine); 71 72 mSharedState = state; 73 mEngineInfo = info; 74 mPreventRadioButtonCallbacks = false; 75 76 setKey(mEngineInfo.name); 77 setTitle(mEngineInfo.label); 78 } 79 80 @Override onBindViewHolder(PreferenceViewHolder view)81 public void onBindViewHolder(PreferenceViewHolder view) { 82 super.onBindViewHolder(view); 83 84 if (mSharedState == null) { 85 throw new IllegalStateException("Call to getView() before a call to" + 86 "setSharedState()"); 87 } 88 89 final RadioButton rb = (RadioButton) view.findViewById(R.id.tts_engine_radiobutton); 90 rb.setOnCheckedChangeListener(mRadioChangeListener); 91 rb.setText(mEngineInfo.label); 92 93 boolean isChecked = getKey().equals(mSharedState.getCurrentKey()); 94 if (isChecked) { 95 mSharedState.setCurrentChecked(rb); 96 } 97 98 mPreventRadioButtonCallbacks = true; 99 rb.setChecked(isChecked); 100 mPreventRadioButtonCallbacks = false; 101 102 mRadioButton = rb; 103 } 104 setVoiceDataDetails(Intent data)105 public void setVoiceDataDetails(Intent data) { 106 mVoiceCheckData = data; 107 } 108 shouldDisplayDataAlert()109 private boolean shouldDisplayDataAlert() { 110 return !mEngineInfo.system; 111 } 112 113 displayDataAlert( DialogInterface.OnClickListener positiveOnClickListener, DialogInterface.OnClickListener negativeOnClickListener)114 private void displayDataAlert( 115 DialogInterface.OnClickListener positiveOnClickListener, 116 DialogInterface.OnClickListener negativeOnClickListener) { 117 Log.i(TAG, "Displaying data alert for :" + mEngineInfo.name); 118 119 AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); 120 builder.setTitle(android.R.string.dialog_alert_title) 121 .setMessage(getContext().getString( 122 R.string.tts_engine_security_warning, mEngineInfo.label)) 123 .setCancelable(true) 124 .setPositiveButton(android.R.string.ok, positiveOnClickListener) 125 .setNegativeButton(android.R.string.cancel, negativeOnClickListener); 126 127 AlertDialog dialog = builder.create(); 128 dialog.show(); 129 } 130 131 onRadioButtonClicked(final CompoundButton buttonView, boolean isChecked)132 private void onRadioButtonClicked(final CompoundButton buttonView, 133 boolean isChecked) { 134 if (mPreventRadioButtonCallbacks || 135 (mSharedState.getCurrentChecked() == buttonView)) { 136 return; 137 } 138 139 if (isChecked) { 140 // Should we alert user? if that's true, delay making engine current one. 141 if (shouldDisplayDataAlert()) { 142 displayDataAlert(new DialogInterface.OnClickListener() { 143 @Override 144 public void onClick(DialogInterface dialog, int which) { 145 makeCurrentEngine(buttonView); 146 } 147 },new DialogInterface.OnClickListener() { 148 @Override 149 public void onClick(DialogInterface dialog, int which) { 150 // Undo the click. 151 buttonView.setChecked(false); 152 } 153 }); 154 } else { 155 // Privileged engine, set it current 156 makeCurrentEngine(buttonView); 157 } 158 } 159 } 160 makeCurrentEngine(Checkable current)161 private void makeCurrentEngine(Checkable current) { 162 if (mSharedState.getCurrentChecked() != null) { 163 mSharedState.getCurrentChecked().setChecked(false); 164 } 165 mSharedState.setCurrentChecked(current); 166 mSharedState.setCurrentKey(getKey()); 167 callChangeListener(mSharedState.getCurrentKey()); 168 } 169 170 171 /** 172 * Holds all state that is common to this group of radio buttons, such 173 * as the currently selected key and the currently checked compound button. 174 * (which corresponds to this key). 175 */ 176 public interface RadioButtonGroupState { getCurrentKey()177 String getCurrentKey(); getCurrentChecked()178 Checkable getCurrentChecked(); 179 setCurrentKey(String key)180 void setCurrentKey(String key); setCurrentChecked(Checkable current)181 void setCurrentChecked(Checkable current); 182 } 183 184 } 185