summaryrefslogtreecommitdiffstats
path: root/src/com/android/settings/voice
diff options
context:
space:
mode:
authorXiyuan Xia <xiyuan@google.com>2015-06-02 14:55:32 -0700
committerXiyuan Xia <xiyuan@google.com>2015-06-10 08:43:28 -0700
commit86a554091d0705f2152fcf1d78ca1c7720d9842c (patch)
treee168fef6ad80da3a545c80101935d68198e438f1 /src/com/android/settings/voice
parent275e6f75208c08eb925048a330ed4aab96e51033 (diff)
downloadpackages_apps_Settings-86a554091d0705f2152fcf1d78ca1c7720d9842c.zip
packages_apps_Settings-86a554091d0705f2152fcf1d78ca1c7720d9842c.tar.gz
packages_apps_Settings-86a554091d0705f2152fcf1d78ca1c7720d9842c.tar.bz2
Implement default assist app setting
- Add "None" support to AppListPreference - Add DefaultAssistPreference to manage assist; - Add AppListPreferenceWithSettings to show a settings icon; - Implement DefaultAssistPreference based on AppListPreferenceWithSettings; - Move voice input settings into ManageAssist and implement it based on AppListPreferenceWithSettings; Bug:20210110 Change-Id: If283b8b55a46b428ecfa6e45dc2123292b1d4302
Diffstat (limited to 'src/com/android/settings/voice')
-rw-r--r--src/com/android/settings/voice/VoiceInputListPreference.java148
-rw-r--r--src/com/android/settings/voice/VoiceInputPreference.java236
-rw-r--r--src/com/android/settings/voice/VoiceInputSettings.java247
3 files changed, 148 insertions, 483 deletions
diff --git a/src/com/android/settings/voice/VoiceInputListPreference.java b/src/com/android/settings/voice/VoiceInputListPreference.java
new file mode 100644
index 0000000..a131d21
--- /dev/null
+++ b/src/com/android/settings/voice/VoiceInputListPreference.java
@@ -0,0 +1,148 @@
+package com.android.settings.voice;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.provider.Settings;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ListAdapter;
+
+import com.android.settings.AppListPreferenceWithSettings;
+import com.android.settings.R;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class VoiceInputListPreference extends AppListPreferenceWithSettings {
+
+ private VoiceInputHelper mHelper;
+
+ // The assist component name to restrict available voice inputs.
+ private ComponentName mAssistRestrict;
+
+ private final List<Integer> mAvailableIndexes = new ArrayList<>();
+
+ public VoiceInputListPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setDialogTitle(R.string.choose_voice_input_title);
+ }
+
+ @Override
+ protected ListAdapter createListAdapter() {
+ return new CustomAdapter(getContext(), getEntries());
+ }
+
+ @Override
+ protected boolean persistString(String value) {
+ for (int i = 0; i < mHelper.mAvailableInteractionInfos.size(); ++i) {
+ VoiceInputHelper.InteractionInfo info = mHelper.mAvailableInteractionInfos.get(i);
+ if (info.key.equals(value)) {
+ Settings.Secure.putString(getContext().getContentResolver(),
+ Settings.Secure.VOICE_INTERACTION_SERVICE, value);
+ Settings.Secure.putString(getContext().getContentResolver(),
+ Settings.Secure.VOICE_RECOGNITION_SERVICE,
+ new ComponentName(info.service.packageName,
+ info.serviceInfo.getRecognitionService())
+ .flattenToShortString());
+ setSummary(getEntry());
+ setSettingsComponent(info.settings);
+ return true;
+ }
+ }
+
+ for (int i = 0; i < mHelper.mAvailableRecognizerInfos.size(); ++i) {
+ VoiceInputHelper.RecognizerInfo info = mHelper.mAvailableRecognizerInfos.get(i);
+ if (info.key.equals(value)) {
+ Settings.Secure.putString(getContext().getContentResolver(),
+ Settings.Secure.VOICE_INTERACTION_SERVICE, "");
+ Settings.Secure.putString(getContext().getContentResolver(),
+ Settings.Secure.VOICE_RECOGNITION_SERVICE, value);
+ setSummary(getEntry());
+ setSettingsComponent(info.settings);
+ return true;
+ }
+ }
+
+ setSettingsComponent(null);
+ return true;
+ }
+
+ @Override
+ public void setPackageNames(CharSequence[] packageNames, CharSequence defaultPackageName) {
+ // Skip since all entries are created from |mHelper|.
+ }
+
+ public void setAssistRestrict(ComponentName assistRestrict) {
+ mAssistRestrict = assistRestrict;
+ }
+
+ public void refreshVoiceInputs() {
+ mHelper = new VoiceInputHelper(getContext());
+ mHelper.buildUi();
+
+ final String assistKey =
+ mAssistRestrict == null ? "" : mAssistRestrict.flattenToShortString();
+
+ mAvailableIndexes.clear();
+ List<CharSequence> entries = new ArrayList<>();
+ List<CharSequence> values = new ArrayList<>();
+ for (int i = 0; i < mHelper.mAvailableInteractionInfos.size(); ++i) {
+ VoiceInputHelper.InteractionInfo info = mHelper.mAvailableInteractionInfos.get(i);
+ entries.add(info.appLabel);
+ values.add(info.key);
+
+ if (info.key.contentEquals(assistKey)) {
+ mAvailableIndexes.add(i);
+ }
+ }
+
+ final boolean assitIsService = !mAvailableIndexes.isEmpty();
+ final int serviceCount = entries.size();
+
+ for (int i = 0; i < mHelper.mAvailableRecognizerInfos.size(); ++i) {
+ VoiceInputHelper.RecognizerInfo info = mHelper.mAvailableRecognizerInfos.get(i);
+ entries.add(info.label);
+ values.add(info.key);
+ if (!assitIsService) {
+ mAvailableIndexes.add(serviceCount + i);
+ }
+ }
+ setEntries(entries.toArray(new CharSequence[entries.size()]));
+ setEntryValues(values.toArray(new CharSequence[values.size()]));
+
+ if (mHelper.mCurrentVoiceInteraction != null) {
+ setValue(mHelper.mCurrentVoiceInteraction.flattenToShortString());
+ } else if (mHelper.mCurrentRecognizer != null) {
+ setValue(mHelper.mCurrentRecognizer.flattenToShortString());
+ } else {
+ setValue(null);
+ }
+ }
+
+ private class CustomAdapter extends ArrayAdapter<CharSequence> {
+
+ public CustomAdapter(Context context, CharSequence[] objects) {
+ super(context, com.android.internal.R.layout.select_dialog_singlechoice_material,
+ android.R.id.text1, objects);
+ }
+
+ @Override
+ public boolean areAllItemsEnabled() {
+ return false;
+ }
+
+ @Override
+ public boolean isEnabled(int position) {
+ return mAvailableIndexes.contains(position);
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View view = super.getView(position, convertView, parent);
+ view.setEnabled(isEnabled(position));
+ return view;
+ }
+ }
+}
diff --git a/src/com/android/settings/voice/VoiceInputPreference.java b/src/com/android/settings/voice/VoiceInputPreference.java
deleted file mode 100644
index 38ef0ca..0000000
--- a/src/com/android/settings/voice/VoiceInputPreference.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.voice;
-
-import android.app.AlertDialog;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.preference.Preference;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Checkable;
-import android.widget.CompoundButton;
-import android.widget.RadioButton;
-
-
-import com.android.settings.R;
-import com.android.settings.Utils;
-
-public final class VoiceInputPreference extends Preference {
-
- private static final String TAG = "VoiceInputPreference";
-
- private final CharSequence mLabel;
-
- private final CharSequence mAppLabel;
-
- private final CharSequence mAlertText;
-
- private final ComponentName mSettingsComponent;
-
- /**
- * The shared radio button state, which button is checked etc.
- */
- private final RadioButtonGroupState mSharedState;
-
- /**
- * When true, the change callbacks on the radio button will not
- * fire.
- */
- private volatile boolean mPreventRadioButtonCallbacks;
-
- private View mSettingsIcon;
- private RadioButton mRadioButton;
-
- private final CompoundButton.OnCheckedChangeListener mRadioChangeListener =
- new CompoundButton.OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- onRadioButtonClicked(buttonView, isChecked);
- }
- };
-
- public VoiceInputPreference(Context context, VoiceInputHelper.BaseInfo info,
- CharSequence summary, CharSequence alertText, RadioButtonGroupState state) {
- super(context);
- setLayoutResource(R.layout.preference_tts_engine);
-
- mSharedState = state;
- mLabel = info.label;
- mAppLabel = info.appLabel;
- mAlertText = alertText;
- mSettingsComponent = info.settings;
- mPreventRadioButtonCallbacks = false;
-
- setKey(info.key);
- setTitle(info.label);
- setSummary(summary);
- }
-
- @Override
- public View getView(View convertView, ViewGroup parent) {
- if (mSharedState == null) {
- throw new IllegalStateException("Call to getView() before a call to" +
- "setSharedState()");
- }
-
- View view = super.getView(convertView, parent);
- final RadioButton rb = (RadioButton) view.findViewById(R.id.tts_engine_radiobutton);
- rb.setOnCheckedChangeListener(mRadioChangeListener);
-
- boolean isChecked = getKey().equals(mSharedState.getCurrentKey());
- if (isChecked) {
- mSharedState.setCurrentChecked(rb);
- }
-
- mPreventRadioButtonCallbacks = true;
- rb.setChecked(isChecked);
- mPreventRadioButtonCallbacks = false;
-
- mRadioButton = rb;
-
- View textLayout = view.findViewById(R.id.tts_engine_pref_text);
- textLayout.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (!rb.isChecked()) {
- onRadioButtonClicked(rb, true);
- }
- }
- });
-
- mSettingsIcon = view.findViewById(R.id.tts_engine_settings);
- mSettingsIcon.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent intent = new Intent(Intent.ACTION_MAIN);
- intent.setComponent(mSettingsComponent);
- getContext().startActivity(new Intent(intent));
- }
- });
- updateCheckedState(isChecked);
-
- return view;
- }
-
- private boolean shouldDisplayAlert() {
- return mAlertText != null;
- }
-
- private void displayAlert(
- final DialogInterface.OnClickListener positiveOnClickListener,
- final DialogInterface.OnClickListener negativeOnClickListener) {
- Log.i(TAG, "Displaying data alert for :" + getKey());
-
- AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
- String msg = String.format(getContext().getResources().getConfiguration().locale,
- mAlertText.toString(), mAppLabel);
- builder.setTitle(android.R.string.dialog_alert_title)
- .setMessage(msg)
- .setCancelable(true)
- .setPositiveButton(android.R.string.ok, positiveOnClickListener)
- .setNegativeButton(android.R.string.cancel, negativeOnClickListener)
- .setOnCancelListener(new DialogInterface.OnCancelListener() {
- @Override public void onCancel(DialogInterface dialog) {
- negativeOnClickListener.onClick(dialog, DialogInterface.BUTTON_NEGATIVE);
- }
- });
-
- AlertDialog dialog = builder.create();
- dialog.show();
- }
-
- public void doClick() {
- mRadioButton.performClick();
- }
-
- void updateCheckedState(boolean isChecked) {
- if (mSettingsComponent != null) {
- mSettingsIcon.setVisibility(View.VISIBLE);
- if (isChecked) {
- mSettingsIcon.setEnabled(true);
- mSettingsIcon.setAlpha(1);
- } else {
- mSettingsIcon.setEnabled(false);
- mSettingsIcon.setAlpha(Utils.DISABLED_ALPHA);
- }
- } else {
- mSettingsIcon.setVisibility(View.GONE);
- }
- }
-
- void onRadioButtonClicked(final CompoundButton buttonView, boolean isChecked) {
- if (mPreventRadioButtonCallbacks) {
- return;
- }
- if (mSharedState.getCurrentChecked() == buttonView) {
- updateCheckedState(isChecked);
- return;
- }
-
- if (isChecked) {
- // Should we alert user? if that's true, delay making engine current one.
- if (shouldDisplayAlert()) {
- displayAlert(new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- makeCurrentChecked(buttonView);
- }
- }, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- // Undo the click.
- buttonView.setChecked(false);
- }
- }
- );
- } else {
- // Privileged engine, set it current
- makeCurrentChecked(buttonView);
- }
- } else {
- updateCheckedState(isChecked);
- }
- }
-
- void makeCurrentChecked(Checkable current) {
- if (mSharedState.getCurrentChecked() != null) {
- mSharedState.getCurrentChecked().setChecked(false);
- }
- mSharedState.setCurrentChecked(current);
- mSharedState.setCurrentKey(getKey());
- updateCheckedState(true);
- callChangeListener(mSharedState.getCurrentKey());
- current.setChecked(true);
- }
-
- /**
- * Holds all state that is common to this group of radio buttons, such
- * as the currently selected key and the currently checked compound button.
- * (which corresponds to this key).
- */
- public interface RadioButtonGroupState {
- String getCurrentKey();
- Checkable getCurrentChecked();
-
- void setCurrentKey(String key);
- void setCurrentChecked(Checkable current);
- }
-}
diff --git a/src/com/android/settings/voice/VoiceInputSettings.java b/src/com/android/settings/voice/VoiceInputSettings.java
deleted file mode 100644
index bac297e..0000000
--- a/src/com/android/settings/voice/VoiceInputSettings.java
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.voice;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
-import android.preference.Preference;
-import android.provider.Settings;
-import android.service.voice.VoiceInteractionService;
-import android.service.voice.VoiceInteractionServiceInfo;
-import android.speech.RecognitionService;
-import com.android.internal.logging.MetricsLogger;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settings.search.Indexable;
-import com.android.settings.search.SearchIndexableRaw;
-import com.android.settings.voice.VoiceInputPreference.RadioButtonGroupState;
-
-import android.os.Bundle;
-import android.preference.PreferenceCategory;
-import android.widget.Checkable;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class VoiceInputSettings extends SettingsPreferenceFragment implements
- Preference.OnPreferenceClickListener, RadioButtonGroupState, Indexable {
-
- private static final String TAG = "VoiceInputSettings";
- private static final boolean DBG = false;
-
- /**
- * Preference key for the engine selection preference.
- */
- private static final String KEY_SERVICE_PREFERENCE_SECTION =
- "voice_service_preference_section";
-
- private PreferenceCategory mServicePreferenceCategory;
-
- private CharSequence mInteractorSummary;
- private CharSequence mRecognizerSummary;
- private CharSequence mInteractorWarning;
-
- /**
- * The currently selected engine.
- */
- private String mCurrentKey;
-
- /**
- * The engine checkbox that is currently checked. Saves us a bit of effort
- * in deducing the right one from the currently selected engine.
- */
- private Checkable mCurrentChecked;
-
- private VoiceInputHelper mHelper;
-
- @Override
- protected int getMetricsCategory() {
- return MetricsLogger.VOICE_INPUT;
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- addPreferencesFromResource(R.xml.voice_input_settings);
-
- mServicePreferenceCategory = (PreferenceCategory) findPreference(
- KEY_SERVICE_PREFERENCE_SECTION);
-
- mInteractorSummary = getActivity().getText(
- R.string.voice_interactor_preference_summary);
- mRecognizerSummary = getActivity().getText(
- R.string.voice_recognizer_preference_summary);
- mInteractorWarning = getActivity().getText(R.string.voice_interaction_security_warning);
- }
-
- @Override
- public void onStart() {
- super.onStart();
- initSettings();
- }
-
- private void initSettings() {
- mHelper = new VoiceInputHelper(getActivity());
- mHelper.buildUi();
-
- mServicePreferenceCategory.removeAll();
-
- if (mHelper.mCurrentVoiceInteraction != null) {
- mCurrentKey = mHelper.mCurrentVoiceInteraction.flattenToShortString();
- } else if (mHelper.mCurrentRecognizer != null) {
- mCurrentKey = mHelper.mCurrentRecognizer.flattenToShortString();
- } else {
- mCurrentKey = null;
- }
-
- for (int i=0; i<mHelper.mAvailableInteractionInfos.size(); i++) {
- VoiceInputHelper.InteractionInfo info = mHelper.mAvailableInteractionInfos.get(i);
- VoiceInputPreference pref = new VoiceInputPreference(getActivity(), info,
- mInteractorSummary, mInteractorWarning, this);
- mServicePreferenceCategory.addPreference(pref);
- }
-
- for (int i=0; i<mHelper.mAvailableRecognizerInfos.size(); i++) {
- VoiceInputHelper.RecognizerInfo info = mHelper.mAvailableRecognizerInfos.get(i);
- VoiceInputPreference pref = new VoiceInputPreference(getActivity(), info,
- mRecognizerSummary, null, this);
- mServicePreferenceCategory.addPreference(pref);
- }
- }
-
- @Override
- public Checkable getCurrentChecked() {
- return mCurrentChecked;
- }
-
- @Override
- public String getCurrentKey() {
- return mCurrentKey;
- }
-
- @Override
- public void setCurrentChecked(Checkable current) {
- mCurrentChecked = current;
- }
-
- @Override
- public void setCurrentKey(String key) {
- mCurrentKey = key;
- for (int i=0; i<mHelper.mAvailableInteractionInfos.size(); i++) {
- VoiceInputHelper.InteractionInfo info = mHelper.mAvailableInteractionInfos.get(i);
- if (info.key.equals(key)) {
- // Put the new value back into secure settings.
- Settings.Secure.putString(getActivity().getContentResolver(),
- Settings.Secure.VOICE_INTERACTION_SERVICE, key);
- Settings.Secure.putString(getActivity().getContentResolver(),
- Settings.Secure.VOICE_RECOGNITION_SERVICE,
- new ComponentName(info.service.packageName,
- info.serviceInfo.getRecognitionService())
- .flattenToShortString());
- return;
- }
- }
-
- for (int i=0; i<mHelper.mAvailableRecognizerInfos.size(); i++) {
- VoiceInputHelper.RecognizerInfo info = mHelper.mAvailableRecognizerInfos.get(i);
- if (info.key.equals(key)) {
- Settings.Secure.putString(getActivity().getContentResolver(),
- Settings.Secure.VOICE_INTERACTION_SERVICE, "");
- Settings.Secure.putString(getActivity().getContentResolver(),
- Settings.Secure.VOICE_RECOGNITION_SERVICE, key);
- return;
- }
- }
- }
-
- @Override
- public boolean onPreferenceClick(Preference preference) {
- if (preference instanceof VoiceInputPreference) {
- ((VoiceInputPreference)preference).doClick();
- }
- return true;
- }
-
- // For Search
- public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
- new BaseSearchIndexProvider() {
-
- @Override
- public List<SearchIndexableRaw> getRawDataToIndex(Context context,
- boolean enabled) {
-
- List<SearchIndexableRaw> indexables = new ArrayList<>();
-
- final String screenTitle = context.getString(R.string.voice_input_settings_title);
-
- SearchIndexableRaw indexable = new SearchIndexableRaw(context);
- indexable.key = "voice_service_preference_section_title";
- indexable.title = context.getString(R.string.voice_service_preference_section_title);
- indexable.screenTitle = screenTitle;
- indexables.add(indexable);
-
- final List<ResolveInfo> voiceInteractions =
- context.getPackageManager().queryIntentServices(
- new Intent(VoiceInteractionService.SERVICE_INTERFACE),
- PackageManager.GET_META_DATA);
-
- final int countInteractions = voiceInteractions.size();
- for (int i = 0; i < countInteractions; i++) {
- ResolveInfo info = voiceInteractions.get(i);
- VoiceInteractionServiceInfo visInfo = new VoiceInteractionServiceInfo(
- context.getPackageManager(), info.serviceInfo);
- if (visInfo.getParseError() != null) {
- continue;
- }
- indexables.add(getSearchIndexableRaw(context, info, screenTitle));
- }
-
- final List<ResolveInfo> recognitions =
- context.getPackageManager().queryIntentServices(
- new Intent(RecognitionService.SERVICE_INTERFACE),
- PackageManager.GET_META_DATA);
-
- final int countRecognitions = recognitions.size();
- for (int i = 0; i < countRecognitions; i++) {
- ResolveInfo info = recognitions.get(i);
- indexables.add(getSearchIndexableRaw(context, info, screenTitle));
- }
-
- return indexables;
- }
-
- private SearchIndexableRaw getSearchIndexableRaw(Context context,
- ResolveInfo info, String screenTitle) {
-
- ServiceInfo serviceInfo = info.serviceInfo;
- ComponentName componentName = new ComponentName(serviceInfo.packageName,
- serviceInfo.name);
-
- SearchIndexableRaw indexable = new SearchIndexableRaw(context);
- indexable.key = componentName.flattenToString();
- indexable.title = info.loadLabel(context.getPackageManager()).toString();
- indexable.screenTitle = screenTitle;
-
- return indexable;
- }
- };
-}