1 package com.android.settings.voice; 2 3 import android.content.ComponentName; 4 import android.content.Context; 5 import android.provider.Settings; 6 import android.util.AttributeSet; 7 import android.view.View; 8 import android.view.ViewGroup; 9 import android.widget.ArrayAdapter; 10 import android.widget.ListAdapter; 11 12 import com.android.settings.AppListPreferenceWithSettings; 13 import com.android.settings.R; 14 15 import java.util.ArrayList; 16 import java.util.List; 17 18 public class VoiceInputListPreference extends AppListPreferenceWithSettings { 19 20 private VoiceInputHelper mHelper; 21 22 // The assist component name to restrict available voice inputs. 23 private ComponentName mAssistRestrict; 24 25 private final List<Integer> mAvailableIndexes = new ArrayList<>(); 26 VoiceInputListPreference(Context context, AttributeSet attrs)27 public VoiceInputListPreference(Context context, AttributeSet attrs) { 28 super(context, attrs); 29 setDialogTitle(R.string.choose_voice_input_title); 30 } 31 32 @Override createListAdapter()33 protected ListAdapter createListAdapter() { 34 return new CustomAdapter(getContext(), getEntries()); 35 } 36 37 @Override persistString(String value)38 protected boolean persistString(String value) { 39 for (int i = 0; i < mHelper.mAvailableInteractionInfos.size(); ++i) { 40 VoiceInputHelper.InteractionInfo info = mHelper.mAvailableInteractionInfos.get(i); 41 if (info.key.equals(value)) { 42 Settings.Secure.putString(getContext().getContentResolver(), 43 Settings.Secure.VOICE_INTERACTION_SERVICE, value); 44 Settings.Secure.putString(getContext().getContentResolver(), 45 Settings.Secure.VOICE_RECOGNITION_SERVICE, 46 new ComponentName(info.service.packageName, 47 info.serviceInfo.getRecognitionService()) 48 .flattenToShortString()); 49 setSummary(getEntry()); 50 setSettingsComponent(info.settings); 51 return true; 52 } 53 } 54 55 for (int i = 0; i < mHelper.mAvailableRecognizerInfos.size(); ++i) { 56 VoiceInputHelper.RecognizerInfo info = mHelper.mAvailableRecognizerInfos.get(i); 57 if (info.key.equals(value)) { 58 Settings.Secure.putString(getContext().getContentResolver(), 59 Settings.Secure.VOICE_INTERACTION_SERVICE, ""); 60 Settings.Secure.putString(getContext().getContentResolver(), 61 Settings.Secure.VOICE_RECOGNITION_SERVICE, value); 62 setSummary(getEntry()); 63 setSettingsComponent(info.settings); 64 return true; 65 } 66 } 67 68 setSettingsComponent(null); 69 return true; 70 } 71 72 @Override setPackageNames(CharSequence[] packageNames, CharSequence defaultPackageName)73 public void setPackageNames(CharSequence[] packageNames, CharSequence defaultPackageName) { 74 // Skip since all entries are created from |mHelper|. 75 } 76 setAssistRestrict(ComponentName assistRestrict)77 public void setAssistRestrict(ComponentName assistRestrict) { 78 mAssistRestrict = assistRestrict; 79 } 80 refreshVoiceInputs()81 public void refreshVoiceInputs() { 82 mHelper = new VoiceInputHelper(getContext()); 83 mHelper.buildUi(); 84 85 final String assistKey = 86 mAssistRestrict == null ? "" : mAssistRestrict.flattenToShortString(); 87 88 mAvailableIndexes.clear(); 89 List<CharSequence> entries = new ArrayList<>(); 90 List<CharSequence> values = new ArrayList<>(); 91 for (int i = 0; i < mHelper.mAvailableInteractionInfos.size(); ++i) { 92 VoiceInputHelper.InteractionInfo info = mHelper.mAvailableInteractionInfos.get(i); 93 entries.add(info.appLabel); 94 values.add(info.key); 95 96 if (info.key.contentEquals(assistKey)) { 97 mAvailableIndexes.add(i); 98 } 99 } 100 101 final boolean assitIsService = !mAvailableIndexes.isEmpty(); 102 final int serviceCount = entries.size(); 103 104 for (int i = 0; i < mHelper.mAvailableRecognizerInfos.size(); ++i) { 105 VoiceInputHelper.RecognizerInfo info = mHelper.mAvailableRecognizerInfos.get(i); 106 entries.add(info.label); 107 values.add(info.key); 108 if (!assitIsService) { 109 mAvailableIndexes.add(serviceCount + i); 110 } 111 } 112 setEntries(entries.toArray(new CharSequence[entries.size()])); 113 setEntryValues(values.toArray(new CharSequence[values.size()])); 114 115 if (mHelper.mCurrentVoiceInteraction != null) { 116 setValue(mHelper.mCurrentVoiceInteraction.flattenToShortString()); 117 } else if (mHelper.mCurrentRecognizer != null) { 118 setValue(mHelper.mCurrentRecognizer.flattenToShortString()); 119 } else { 120 setValue(null); 121 } 122 } 123 getCurrentService()124 public ComponentName getCurrentService() { 125 if (mHelper.mCurrentVoiceInteraction != null) { 126 return mHelper.mCurrentVoiceInteraction; 127 } else if (mHelper.mCurrentRecognizer != null) { 128 return mHelper.mCurrentRecognizer; 129 } else { 130 return null; 131 } 132 } 133 134 private class CustomAdapter extends ArrayAdapter<CharSequence> { 135 CustomAdapter(Context context, CharSequence[] objects)136 public CustomAdapter(Context context, CharSequence[] objects) { 137 super(context, com.android.internal.R.layout.select_dialog_singlechoice_material, 138 android.R.id.text1, objects); 139 } 140 141 @Override areAllItemsEnabled()142 public boolean areAllItemsEnabled() { 143 return false; 144 } 145 146 @Override isEnabled(int position)147 public boolean isEnabled(int position) { 148 return mAvailableIndexes.contains(position); 149 } 150 151 @Override getView(int position, View convertView, ViewGroup parent)152 public View getView(int position, View convertView, ViewGroup parent) { 153 View view = super.getView(position, convertView, parent); 154 view.setEnabled(isEnabled(position)); 155 return view; 156 } 157 } 158 } 159