• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.content.Context;
20 import android.content.Intent;
21 import android.os.Bundle;
22 import android.preference.Preference;
23 import android.preference.PreferenceActivity;
24 import android.speech.tts.TextToSpeech.EngineInfo;
25 import android.view.View;
26 import android.view.ViewGroup;
27 import android.widget.Checkable;
28 import android.widget.CompoundButton;
29 import android.widget.RadioButton;
30 
31 
32 import com.android.settings.R;
33 
34 
35 public class TtsEnginePreference extends Preference {
36 
37     /**
38      * Key for the name of the TTS engine passed in to the engine
39      * settings fragment {@link TtsEngineSettingsFragment}.
40      */
41     static final String FRAGMENT_ARGS_NAME = "name";
42 
43     /**
44      * Key for the label of the TTS engine passed in to the engine
45      * settings fragment. This is used as the title of the fragment
46      * {@link TtsEngineSettingsFragment}.
47      */
48     static final String FRAGMENT_ARGS_LABEL = "label";
49 
50     /**
51      * Key for the voice data data passed in to the engine settings
52      * fragmetn {@link TtsEngineSettingsFragment}.
53      */
54     static final String FRAGMENT_ARGS_VOICES = "voices";
55 
56     /**
57      * The preference activity that owns this preference. Required
58      * for instantiating the engine specific settings screen.
59      */
60     private final PreferenceActivity mPreferenceActivity;
61 
62     /**
63      * The engine information for the engine this preference represents.
64      * Contains it's name, label etc. which are used for display.
65      */
66     private final EngineInfo mEngineInfo;
67 
68     /**
69      * The shared radio button state, which button is checked etc.
70      */
71     private final RadioButtonGroupState mSharedState;
72 
73     /**
74      * When true, the change callbacks on the radio button will not
75      * fire.
76      */
77     private volatile boolean mPreventRadioButtonCallbacks;
78 
79     private View mSettingsIcon;
80     private RadioButton mRadioButton;
81     private Intent mVoiceCheckData;
82 
83     private final CompoundButton.OnCheckedChangeListener mRadioChangeListener =
84         new CompoundButton.OnCheckedChangeListener() {
85             @Override
86             public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
87                 onRadioButtonClicked(buttonView, isChecked);
88             }
89         };
90 
TtsEnginePreference(Context context, EngineInfo info, RadioButtonGroupState state, PreferenceActivity prefActivity)91     public TtsEnginePreference(Context context, EngineInfo info, RadioButtonGroupState state,
92             PreferenceActivity prefActivity) {
93         super(context);
94         setLayoutResource(R.layout.preference_tts_engine);
95 
96         mSharedState = state;
97         mPreferenceActivity = prefActivity;
98         mEngineInfo = info;
99         mPreventRadioButtonCallbacks = false;
100 
101         setKey(mEngineInfo.name);
102         setTitle(mEngineInfo.label);
103     }
104 
105     @Override
getView(View convertView, ViewGroup parent)106     public View getView(View convertView, ViewGroup parent) {
107         if (mSharedState == null) {
108             throw new IllegalStateException("Call to getView() before a call to" +
109                     "setSharedState()");
110         }
111 
112         View view = super.getView(convertView, parent);
113         final RadioButton rb = (RadioButton) view.findViewById(R.id.tts_engine_radiobutton);
114         rb.setOnCheckedChangeListener(mRadioChangeListener);
115 
116         boolean isChecked = getKey().equals(mSharedState.getCurrentKey());
117         if (isChecked) {
118             mSharedState.setCurrentChecked(rb);
119         }
120 
121         mPreventRadioButtonCallbacks = true;
122         rb.setChecked(isChecked);
123         mPreventRadioButtonCallbacks = false;
124 
125         mRadioButton = rb;
126 
127         View textLayout = view.findViewById(R.id.tts_engine_pref_text);
128         textLayout.setOnClickListener(new View.OnClickListener() {
129             @Override
130             public void onClick(View v) {
131                 onRadioButtonClicked(rb, !rb.isChecked());
132             }
133         });
134 
135         mSettingsIcon = view.findViewById(R.id.tts_engine_settings);
136         // Will be enabled only the engine has passed the voice check, and
137         // is currently enabled.
138         mSettingsIcon.setEnabled(isChecked && mVoiceCheckData != null);
139         mSettingsIcon.setOnClickListener(new View.OnClickListener() {
140             @Override
141             public void onClick(View v) {
142                 Bundle args = new Bundle();
143                 args.putString(FRAGMENT_ARGS_NAME, mEngineInfo.name);
144                 args.putString(FRAGMENT_ARGS_LABEL, mEngineInfo.label);
145                 if (mVoiceCheckData != null) {
146                     args.putParcelable(FRAGMENT_ARGS_VOICES, mVoiceCheckData);
147                 }
148 
149                 // Note that we use this instead of the (easier to use)
150                 // PreferenceActivity.startPreferenceFragment because the
151                 // title will not be updated correctly in the fragment
152                 // breadcrumb since it isn't inflated from the XML layout.
153                 mPreferenceActivity.startPreferencePanel(
154                         TtsEngineSettingsFragment.class.getName(),
155                         args, 0, mEngineInfo.label, null, 0);
156             }
157         });
158 
159         if (mVoiceCheckData != null) {
160             mSettingsIcon.setEnabled(mRadioButton.isChecked());
161         }
162 
163         return view;
164     }
165 
setVoiceDataDetails(Intent data)166     public void setVoiceDataDetails(Intent data) {
167         mVoiceCheckData = data;
168         // This might end up running before getView aboive, in which
169         // case mSettingsIcon && mRadioButton will be null. In this case
170         // getView will set the right values.
171         if (mSettingsIcon != null && mRadioButton != null) {
172             mSettingsIcon.setEnabled(mRadioButton.isChecked());
173         }
174     }
175 
onRadioButtonClicked(CompoundButton buttonView, boolean isChecked)176     private void onRadioButtonClicked(CompoundButton buttonView, boolean isChecked) {
177         if (mPreventRadioButtonCallbacks ||
178                 (mSharedState.getCurrentChecked() == buttonView)) {
179             return;
180         }
181 
182         if (isChecked) {
183             if (mSharedState.getCurrentChecked() != null) {
184                 mSharedState.getCurrentChecked().setChecked(false);
185             }
186             mSharedState.setCurrentChecked(buttonView);
187             mSharedState.setCurrentKey(getKey());
188             callChangeListener(mSharedState.getCurrentKey());
189         }
190 
191         mSettingsIcon.setEnabled(isChecked);
192     }
193 
194 
195     /**
196      * Holds all state that is common to this group of radio buttons, such
197      * as the currently selected key and the currently checked compound button.
198      * (which corresponds to this key).
199      */
200     public interface RadioButtonGroupState {
getCurrentKey()201         String getCurrentKey();
getCurrentChecked()202         Checkable getCurrentChecked();
203 
setCurrentKey(String key)204         void setCurrentKey(String key);
setCurrentChecked(Checkable current)205         void setCurrentChecked(Checkable current);
206     }
207 
208 }
209