diff options
author | Dianne Hackborn <hackbod@google.com> | 2014-07-18 19:20:11 -0700 |
---|---|---|
committer | Dianne Hackborn <hackbod@google.com> | 2014-07-21 20:14:43 -0700 |
commit | ff795ffba80e8a6455f27fab7ad0e8e14e2ec9a4 (patch) | |
tree | 9f6ce9f2f7d33865be69e451b9b383aa11590e74 /src/com/android/settings/VoiceInputOutputSettings.java | |
parent | f6f1e2ba1382617cc4df76a004a0da4313a59129 (diff) | |
download | packages_apps_Settings-ff795ffba80e8a6455f27fab7ad0e8e14e2ec9a4.zip packages_apps_Settings-ff795ffba80e8a6455f27fab7ad0e8e14e2ec9a4.tar.gz packages_apps_Settings-ff795ffba80e8a6455f27fab7ad0e8e14e2ec9a4.tar.bz2 |
Unify voice interactor and recognizer settings.
There is now one settings UI to select both the new
voice interactor and old voice recognizer.
There are still a few wonky things about this that won't
be resolved until we start requiring that all interactors
specify an associated recognizer service.
Change-Id: Ib702ff717fb28bcb244cb30e49577066ddc9f197
Diffstat (limited to 'src/com/android/settings/VoiceInputOutputSettings.java')
-rw-r--r-- | src/com/android/settings/VoiceInputOutputSettings.java | 341 |
1 files changed, 11 insertions, 330 deletions
diff --git a/src/com/android/settings/VoiceInputOutputSettings.java b/src/com/android/settings/VoiceInputOutputSettings.java index 64f8a09..e052f8e 100644 --- a/src/com/android/settings/VoiceInputOutputSettings.java +++ b/src/com/android/settings/VoiceInputOutputSettings.java @@ -16,65 +16,31 @@ package com.android.settings; -import android.Manifest; -import android.content.ComponentName; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.content.pm.ServiceInfo; -import android.content.pm.PackageManager.NameNotFoundException; -import android.content.res.Resources; -import android.content.res.TypedArray; -import android.content.res.XmlResourceParser; -import android.preference.ListPreference; import android.preference.Preference; import android.preference.PreferenceCategory; import android.preference.PreferenceGroup; -import android.preference.PreferenceScreen; -import android.preference.Preference.OnPreferenceChangeListener; -import android.provider.Settings; -import android.service.voice.VoiceInteractionService; -import android.speech.RecognitionService; import android.speech.tts.TtsEngines; -import android.util.AttributeSet; -import android.util.Log; -import android.util.Xml; -import java.io.IOException; -import java.util.HashMap; -import java.util.List; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; +import com.android.settings.voice.VoiceInputHelper; /** * Settings screen for voice input/output. */ -public class VoiceInputOutputSettings implements OnPreferenceChangeListener { +public class VoiceInputOutputSettings { private static final String TAG = "VoiceInputOutputSettings"; private static final String KEY_VOICE_CATEGORY = "voice_category"; - private static final String KEY_VOICE_INTERACTOR = "voice_interactor"; - private static final String KEY_VOICE_INTERACTOR_SETTINGS = "voice_interactor_settings"; - private static final String KEY_RECOGNIZER = "recognizer"; - private static final String KEY_RECOGNIZER_SETTINGS = "recognizer_settings"; + private static final String KEY_VOICE_INPUT_SETTINGS = "voice_input_settings"; private static final String KEY_TTS_SETTINGS = "tts_settings"; private PreferenceGroup mParent; - private ListPreference mVoiceInteractionPref; - private PreferenceScreen mVoiceInteractionSettingsPref; private PreferenceCategory mVoiceCategory; - private ListPreference mRecognizerPref; - private PreferenceScreen mRecognizerSettingsPref; + private Preference mVoiceInputSettingsPref; private Preference mTtsSettingsPref; private final SettingsPreferenceFragment mFragment; private final TtsEngines mTtsEngines; - private HashMap<String, ResolveInfo> mAvailableVoiceInteractionsMap; - - private HashMap<String, ResolveInfo> mAvailableRecognizersMap; - public VoiceInputOutputSettings(SettingsPreferenceFragment fragment) { mFragment = fragment; mTtsEngines = new TtsEngines(fragment.getPreferenceScreen().getContext()); @@ -84,28 +50,16 @@ public class VoiceInputOutputSettings implements OnPreferenceChangeListener { mParent = mFragment.getPreferenceScreen(); mVoiceCategory = (PreferenceCategory) mParent.findPreference(KEY_VOICE_CATEGORY); - mVoiceInteractionPref = (ListPreference) mVoiceCategory.findPreference( - KEY_VOICE_INTERACTOR); - mVoiceInteractionPref.setOnPreferenceChangeListener(this); - mVoiceInteractionSettingsPref = (PreferenceScreen)mVoiceCategory.findPreference( - KEY_VOICE_INTERACTOR_SETTINGS); - mRecognizerPref = (ListPreference) mVoiceCategory.findPreference(KEY_RECOGNIZER); - mRecognizerSettingsPref = (PreferenceScreen) - mVoiceCategory.findPreference(KEY_RECOGNIZER_SETTINGS); - mRecognizerPref.setOnPreferenceChangeListener(this); + mVoiceInputSettingsPref = mVoiceCategory.findPreference(KEY_VOICE_INPUT_SETTINGS); mTtsSettingsPref = mVoiceCategory.findPreference(KEY_TTS_SETTINGS); - mAvailableVoiceInteractionsMap = new HashMap<String, ResolveInfo>(); - mAvailableRecognizersMap = new HashMap<String, ResolveInfo>(); - populateOrRemovePreferences(); } private void populateOrRemovePreferences() { - boolean hasVoiceInteractionPrefs = populateOrRemoveVoiceInteractionPrefs(); - boolean hasRecognizerPrefs = populateOrRemoveRecognizerPrefs(); + boolean hasVoiceInputPrefs = populateOrRemoveVoiceInputPrefs(); boolean hasTtsPrefs = populateOrRemoveTtsPrefs(); - if (!hasVoiceInteractionPrefs && !hasRecognizerPrefs && !hasTtsPrefs) { + if (!hasVoiceInputPrefs && !hasTtsPrefs) { // There were no TTS settings and no recognizer settings, // so it should be safe to hide the preference category // entirely. @@ -113,68 +67,13 @@ public class VoiceInputOutputSettings implements OnPreferenceChangeListener { } } - private boolean populateOrRemoveVoiceInteractionPrefs() { - List<ResolveInfo> availableVoiceServices = - mFragment.getPackageManager().queryIntentServices( - new Intent(VoiceInteractionService.SERVICE_INTERFACE), - PackageManager.GET_META_DATA); - for (int i=0; i<availableVoiceServices.size(); i++) { - ResolveInfo ri = availableVoiceServices.get(i); - if (!Manifest.permission.BIND_VOICE_INTERACTION.equals(ri.serviceInfo.permission)) { - availableVoiceServices.remove(i); - } - } - int numAvailable = availableVoiceServices.size(); - - if (numAvailable == 0) { - mVoiceCategory.removePreference(mVoiceInteractionPref); - mVoiceCategory.removePreference(mVoiceInteractionSettingsPref); + private boolean populateOrRemoveVoiceInputPrefs() { + VoiceInputHelper helper = new VoiceInputHelper(mFragment.getActivity()); + if (!helper.hasItems()) { + mVoiceCategory.removePreference(mVoiceInputSettingsPref); return false; } - populateVoiceInteractionPreference(availableVoiceServices); - - // In this case, there was at least one available recognizer so - // we populated the settings. - return true; - } - - private boolean populateOrRemoveRecognizerPrefs() { - List<ResolveInfo> availableRecognitionServices = - mFragment.getPackageManager().queryIntentServices( - new Intent(RecognitionService.SERVICE_INTERFACE), - PackageManager.GET_META_DATA); - int numAvailable = availableRecognitionServices.size(); - - if (numAvailable == 0) { - mVoiceCategory.removePreference(mRecognizerPref); - mVoiceCategory.removePreference(mRecognizerSettingsPref); - return false; - } - - if (numAvailable == 1) { - // Only one recognizer available, so don't show the list of choices, but do - // set up the link to settings for the available recognizer. - mVoiceCategory.removePreference(mRecognizerPref); - - // But first set up the available recognizers map with just the one recognizer. - ResolveInfo resolveInfo = availableRecognitionServices.get(0); - String recognizerComponent = - new ComponentName(resolveInfo.serviceInfo.packageName, - resolveInfo.serviceInfo.name).flattenToShortString(); - - mAvailableRecognizersMap.put(recognizerComponent, resolveInfo); - - String currentSetting = Settings.Secure.getString( - mFragment.getContentResolver(), Settings.Secure.VOICE_RECOGNITION_SERVICE); - updateRecognizerSettingsLink(currentSetting); - } else { - // Multiple recognizers available, so show the full list of choices. - populateRecognizerPreference(availableRecognitionServices); - } - - // In this case, there was at least one available recognizer so - // we populated the settings. return true; } @@ -186,222 +85,4 @@ public class VoiceInputOutputSettings implements OnPreferenceChangeListener { return true; } - - private void populateVoiceInteractionPreference(List<ResolveInfo> voiceInteractors) { - int size = voiceInteractors.size(); - CharSequence[] entries = new CharSequence[size+1]; - CharSequence[] values = new CharSequence[size+1]; - - // Get the current value from the secure setting. - String currentSetting = Settings.Secure.getString( - mFragment.getContentResolver(), Settings.Secure.VOICE_INTERACTION_SERVICE); - - // Iterate through all the available recognizers and load up their info to show - // in the preference. Also build up a map of recognizer component names to their - // ResolveInfos - we'll need that a little later. - for (int i = 0; i < size; i++) { - ResolveInfo resolveInfo = voiceInteractors.get(i); - String recognizerComponent = - new ComponentName(resolveInfo.serviceInfo.packageName, - resolveInfo.serviceInfo.name).flattenToShortString(); - - mAvailableVoiceInteractionsMap.put(recognizerComponent, resolveInfo); - - entries[i] = resolveInfo.loadLabel(mFragment.getPackageManager()); - values[i] = recognizerComponent; - } - - entries[size] = mFragment.getString(R.string.no_voice_interactor); - values[size] = ""; - - mVoiceInteractionPref.setEntries(entries); - mVoiceInteractionPref.setEntryValues(values); - - mVoiceInteractionPref.setDefaultValue(currentSetting); - mVoiceInteractionPref.setValue(currentSetting); - - updateVoiceInteractionSettingsLink(currentSetting); - } - - private void updateVoiceInteractionSettingsLink(String currentSetting) { - ResolveInfo currentRecognizer = mAvailableVoiceInteractionsMap.get(currentSetting); - if (currentRecognizer == null) { - mVoiceInteractionPref.setSummary(mFragment.getString(R.string.no_voice_interactor)); - mVoiceInteractionPref.setValue(""); - return; - } - - ServiceInfo si = currentRecognizer.serviceInfo; - XmlResourceParser parser = null; - String settingsActivity = null; - try { - parser = si.loadXmlMetaData(mFragment.getPackageManager(), - VoiceInteractionService.SERVICE_META_DATA); - if (parser == null) { - throw new XmlPullParserException("No " + VoiceInteractionService.SERVICE_META_DATA + - " meta-data for " + si.packageName); - } - - Resources res = mFragment.getPackageManager().getResourcesForApplication( - si.applicationInfo); - - AttributeSet attrs = Xml.asAttributeSet(parser); - - int type; - while ((type=parser.next()) != XmlPullParser.END_DOCUMENT - && type != XmlPullParser.START_TAG) { - } - - String nodeName = parser.getName(); - if (!"voice-interaction-service".equals(nodeName)) { - throw new XmlPullParserException( - "Meta-data does not start with voice-interaction-service tag"); - } - - TypedArray array = res.obtainAttributes(attrs, - com.android.internal.R.styleable.VoiceInteractionService); - settingsActivity = array.getString( - com.android.internal.R.styleable.VoiceInteractionService_settingsActivity); - array.recycle(); - } catch (XmlPullParserException e) { - Log.e(TAG, "error parsing recognition service meta-data", e); - } catch (IOException e) { - Log.e(TAG, "error parsing recognition service meta-data", e); - } catch (NameNotFoundException e) { - Log.e(TAG, "error parsing recognition service meta-data", e); - } finally { - if (parser != null) parser.close(); - } - - mVoiceInteractionPref.setSummary(currentRecognizer.loadLabel( - mFragment.getPackageManager())); - mVoiceInteractionPref.setValue(currentSetting); - - if (settingsActivity == null) { - // No settings preference available - hide the preference. - Log.w(TAG, "no recognizer settings available for " + si.packageName); - } else { - Intent i = new Intent(Intent.ACTION_MAIN); - i.setComponent(new ComponentName(si.packageName, settingsActivity)); - mVoiceInteractionSettingsPref.setIntent(i); - } - } - - private void populateRecognizerPreference(List<ResolveInfo> recognizers) { - int size = recognizers.size(); - CharSequence[] entries = new CharSequence[size]; - CharSequence[] values = new CharSequence[size]; - - // Get the current value from the secure setting. - String currentSetting = Settings.Secure.getString( - mFragment.getContentResolver(), Settings.Secure.VOICE_RECOGNITION_SERVICE); - - // Iterate through all the available recognizers and load up their info to show - // in the preference. Also build up a map of recognizer component names to their - // ResolveInfos - we'll need that a little later. - for (int i = 0; i < size; i++) { - ResolveInfo resolveInfo = recognizers.get(i); - String recognizerComponent = - new ComponentName(resolveInfo.serviceInfo.packageName, - resolveInfo.serviceInfo.name).flattenToShortString(); - - mAvailableRecognizersMap.put(recognizerComponent, resolveInfo); - - entries[i] = resolveInfo.loadLabel(mFragment.getPackageManager()); - values[i] = recognizerComponent; - } - - mRecognizerPref.setEntries(entries); - mRecognizerPref.setEntryValues(values); - - mRecognizerPref.setDefaultValue(currentSetting); - mRecognizerPref.setValue(currentSetting); - - updateRecognizerSettingsLink(currentSetting); - } - - private void updateRecognizerSettingsLink(String currentSetting) { - ResolveInfo currentRecognizer = mAvailableRecognizersMap.get(currentSetting); - if (currentRecognizer == null) return; - - ServiceInfo si = currentRecognizer.serviceInfo; - XmlResourceParser parser = null; - String settingsActivity = null; - try { - parser = si.loadXmlMetaData(mFragment.getPackageManager(), - RecognitionService.SERVICE_META_DATA); - if (parser == null) { - throw new XmlPullParserException("No " + RecognitionService.SERVICE_META_DATA + - " meta-data for " + si.packageName); - } - - Resources res = mFragment.getPackageManager().getResourcesForApplication( - si.applicationInfo); - - AttributeSet attrs = Xml.asAttributeSet(parser); - - int type; - while ((type=parser.next()) != XmlPullParser.END_DOCUMENT - && type != XmlPullParser.START_TAG) { - } - - String nodeName = parser.getName(); - if (!"recognition-service".equals(nodeName)) { - throw new XmlPullParserException( - "Meta-data does not start with recognition-service tag"); - } - - TypedArray array = res.obtainAttributes(attrs, - com.android.internal.R.styleable.RecognitionService); - settingsActivity = array.getString( - com.android.internal.R.styleable.RecognitionService_settingsActivity); - array.recycle(); - } catch (XmlPullParserException e) { - Log.e(TAG, "error parsing recognition service meta-data", e); - } catch (IOException e) { - Log.e(TAG, "error parsing recognition service meta-data", e); - } catch (NameNotFoundException e) { - Log.e(TAG, "error parsing recognition service meta-data", e); - } finally { - if (parser != null) parser.close(); - } - - if (settingsActivity == null) { - // No settings preference available - hide the preference. - Log.w(TAG, "no recognizer settings available for " + si.packageName); - mRecognizerSettingsPref.setIntent(null); - mVoiceCategory.removePreference(mRecognizerSettingsPref); - } else { - Intent i = new Intent(Intent.ACTION_MAIN); - i.setComponent(new ComponentName(si.packageName, settingsActivity)); - mRecognizerSettingsPref.setIntent(i); - mRecognizerPref.setSummary(currentRecognizer.loadLabel(mFragment.getPackageManager())); - } - } - - public boolean onPreferenceChange(Preference preference, Object newValue) { - if (preference == mVoiceInteractionPref) { - String setting = (String) newValue; - - // Put the new value back into secure settings. - Settings.Secure.putString(mFragment.getContentResolver(), - Settings.Secure.VOICE_INTERACTION_SERVICE, - setting); - - // Update the settings item so it points to the right settings. - updateVoiceInteractionSettingsLink(setting); - - } else if (preference == mRecognizerPref) { - String setting = (String) newValue; - - // Put the new value back into secure settings. - Settings.Secure.putString(mFragment.getContentResolver(), - Settings.Secure.VOICE_RECOGNITION_SERVICE, - setting); - - // Update the settings item so it points to the right settings. - updateRecognizerSettingsLink(setting); - } - return true; - } } |