summaryrefslogtreecommitdiffstats
path: root/src/com/android
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
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')
-rw-r--r--src/com/android/settings/AppListPreference.java84
-rw-r--r--src/com/android/settings/AppListPreferenceWithSettings.java59
-rw-r--r--src/com/android/settings/Settings.java2
-rw-r--r--src/com/android/settings/SettingsActivity.java4
-rw-r--r--src/com/android/settings/VoiceInputOutputSettings.java16
-rw-r--r--src/com/android/settings/applications/DefaultAssistPreference.java215
-rw-r--r--src/com/android/settings/applications/ManageAssist.java73
-rw-r--r--src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java8
-rw-r--r--src/com/android/settings/search/Ranking.java2
-rw-r--r--src/com/android/settings/search/SearchIndexableResources.java8
-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
13 files changed, 554 insertions, 548 deletions
diff --git a/src/com/android/settings/AppListPreference.java b/src/com/android/settings/AppListPreference.java
index 3cc91cd..d5e0c3b 100644
--- a/src/com/android/settings/AppListPreference.java
+++ b/src/com/android/settings/AppListPreference.java
@@ -35,13 +35,20 @@ import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.TextView;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* Extends ListPreference to allow us to show the icons for a given list of applications. We do this
* because the names of applications are very similar and the user may not be able to determine what
* app they are selecting without an icon.
*/
public class AppListPreference extends ListPreference {
+
+ public static final String ITEM_NONE_VALUE = "";
+
private Drawable[] mEntryDrawables;
+ private boolean mShowItemNone = false;
public class AppArrayAdapter extends ArrayAdapter<CharSequence> {
private Drawable[] mImageDrawables = null;
@@ -78,38 +85,45 @@ public class AppListPreference extends ListPreference {
super(context, attrs);
}
+ public void setShowItemNone(boolean showItemNone) {
+ mShowItemNone = showItemNone;
+ }
+
public void setPackageNames(CharSequence[] packageNames, CharSequence defaultPackageName) {
// Look up all package names in PackageManager. Skip ones we can't find.
- int foundPackages = 0;
PackageManager pm = getContext().getPackageManager();
- ApplicationInfo[] appInfos = new ApplicationInfo[packageNames.length];
+ final int entryCount = packageNames.length + (mShowItemNone ? 1 : 0);
+ List<CharSequence> applicationNames = new ArrayList<>(entryCount);
+ List<CharSequence> validatedPackageNames = new ArrayList<>(entryCount);
+ List<Drawable> entryDrawables = new ArrayList<>(entryCount);
+ int selectedIndex = -1;
for (int i = 0; i < packageNames.length; i++) {
try {
- appInfos[i] = pm.getApplicationInfo(packageNames[i].toString(), 0);
- foundPackages++;
- } catch (NameNotFoundException e) {
- // Leave appInfos[i] uninitialized; it will be skipped in the list.
- }
- }
-
- // Show the label and icon for each application package.
- CharSequence[] applicationNames = new CharSequence[foundPackages];
- mEntryDrawables = new Drawable[foundPackages];
- int index = 0;
- int selectedIndex = -1;
- for (ApplicationInfo appInfo : appInfos) {
- if (appInfo != null) {
- applicationNames[index] = appInfo.loadLabel(pm);
- mEntryDrawables[index] = appInfo.loadIcon(pm);
+ ApplicationInfo appInfo = pm.getApplicationInfo(packageNames[i].toString(), 0);
+ applicationNames.add(appInfo.loadLabel(pm));
+ validatedPackageNames.add(appInfo.packageName);
+ entryDrawables.add(appInfo.loadIcon(pm));
if (defaultPackageName != null &&
appInfo.packageName.contentEquals(defaultPackageName)) {
- selectedIndex = index;
+ selectedIndex = i;
}
- index++;
+ } catch (NameNotFoundException e) {
+ // Skip unknown packages.
}
}
- setEntries(applicationNames);
- setEntryValues(packageNames);
+
+ if (mShowItemNone) {
+ applicationNames.add(
+ getContext().getResources().getText(R.string.app_list_preference_none));
+ validatedPackageNames.add(ITEM_NONE_VALUE);
+ entryDrawables.add(getContext().getDrawable(R.drawable.ic_remove_circle));
+ }
+
+ setEntries(applicationNames.toArray(new CharSequence[applicationNames.size()]));
+ setEntryValues(
+ validatedPackageNames.toArray(new CharSequence[validatedPackageNames.size()]));
+ mEntryDrawables = entryDrawables.toArray(new Drawable[entryDrawables.size()]);
+
if (selectedIndex != -1) {
setValueIndex(selectedIndex);
} else {
@@ -117,25 +131,32 @@ public class AppListPreference extends ListPreference {
}
}
+ protected ListAdapter createListAdapter() {
+ final String selectedValue = getValue();
+ final boolean selectedNone = selectedValue == null ||
+ (mShowItemNone && selectedValue.contentEquals(ITEM_NONE_VALUE));
+ int selectedIndex = selectedNone ? -1 : findIndexOfValue(selectedValue);
+ return new AppArrayAdapter(getContext(),
+ R.layout.app_preference_item, getEntries(), mEntryDrawables, selectedIndex);
+ }
+
@Override
protected void onPrepareDialogBuilder(Builder builder) {
- int selectedIndex = findIndexOfValue(getValue());
- ListAdapter adapter = new AppArrayAdapter(getContext(),
- R.layout.app_preference_item, getEntries(), mEntryDrawables, selectedIndex);
- builder.setAdapter(adapter, this);
+ builder.setAdapter(createListAdapter(), this);
super.onPrepareDialogBuilder(builder);
}
@Override
protected Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
- return new SavedState(getEntryValues(), getValue(), superState);
+ return new SavedState(getEntryValues(), getValue(), mShowItemNone, superState);
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
if (state instanceof SavedState) {
SavedState savedState = (SavedState) state;
+ mShowItemNone = savedState.showItemNone;
setPackageNames(savedState.entryValues, savedState.value);
super.onRestoreInstanceState(savedState.superState);
} else {
@@ -147,11 +168,14 @@ public class AppListPreference extends ListPreference {
public final CharSequence[] entryValues;
public final CharSequence value;
+ public final boolean showItemNone;
public final Parcelable superState;
- public SavedState(CharSequence[] entryValues, CharSequence value, Parcelable superState) {
+ public SavedState(CharSequence[] entryValues, CharSequence value, boolean showItemNone,
+ Parcelable superState) {
this.entryValues = entryValues;
this.value = value;
+ this.showItemNone = showItemNone;
this.superState = superState;
}
@@ -164,6 +188,7 @@ public class AppListPreference extends ListPreference {
public void writeToParcel(Parcel dest, int flags) {
dest.writeCharSequenceArray(entryValues);
dest.writeCharSequence(value);
+ dest.writeInt(showItemNone ? 1 : 0);
dest.writeParcelable(superState, flags);
}
@@ -172,8 +197,9 @@ public class AppListPreference extends ListPreference {
public SavedState createFromParcel(Parcel source) {
CharSequence[] entryValues = source.readCharSequenceArray();
CharSequence value = source.readCharSequence();
+ boolean showItemNone = source.readInt() != 0;
Parcelable superState = source.readParcelable(getClass().getClassLoader());
- return new SavedState(entryValues, value, superState);
+ return new SavedState(entryValues, value, showItemNone, superState);
}
@Override
diff --git a/src/com/android/settings/AppListPreferenceWithSettings.java b/src/com/android/settings/AppListPreferenceWithSettings.java
new file mode 100644
index 0000000..bbbd332
--- /dev/null
+++ b/src/com/android/settings/AppListPreferenceWithSettings.java
@@ -0,0 +1,59 @@
+package com.android.settings;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * An AppListPreference with optional settings button.
+ */
+public class AppListPreferenceWithSettings extends AppListPreference {
+
+ private View mSettingsIcon;
+ private ComponentName mSettingsComponent;
+
+ public AppListPreferenceWithSettings(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setWidgetLayoutResource(R.layout.preference_widget_settings);
+ }
+
+ @Override
+ protected void onBindView(View view) {
+ super.onBindView(view);
+
+ mSettingsIcon = view.findViewById(R.id.settings_button);
+ 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));
+ }
+ });
+
+ ViewGroup container = (ViewGroup) mSettingsIcon.getParent();
+ container.setPaddingRelative(0, 0, 0, 0);
+
+ updateSettingsVisibility();
+ }
+
+ private void updateSettingsVisibility() {
+ if (mSettingsIcon == null) {
+ return;
+ }
+
+ if (mSettingsComponent == null) {
+ mSettingsIcon.setVisibility(View.GONE);
+ } else {
+ mSettingsIcon.setVisibility(View.VISIBLE);
+ }
+ }
+
+ protected void setSettingsComponent(ComponentName settings) {
+ mSettingsComponent = settings;
+ updateSettingsVisibility();
+ }
+}
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 5a6a2f0..5fb94f0 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -41,7 +41,6 @@ public class Settings extends SettingsActivity {
public static class InputMethodAndLanguageSettingsActivity extends SettingsActivity { /* empty */ }
public static class KeyboardLayoutPickerActivity extends SettingsActivity { /* empty */ }
public static class InputMethodAndSubtypeEnablerActivity extends SettingsActivity { /* empty */ }
- public static class VoiceInputSettingsActivity extends SettingsActivity { /* empty */ }
public static class SpellCheckersSettingsActivity extends SettingsActivity { /* empty */ }
public static class LocalePickerActivity extends SettingsActivity { /* empty */ }
public static class UserDictionarySettingsActivity extends SettingsActivity { /* empty */ }
@@ -50,6 +49,7 @@ public class Settings extends SettingsActivity {
public static class DeviceInfoSettingsActivity extends SettingsActivity { /* empty */ }
public static class ApplicationSettingsActivity extends SettingsActivity { /* empty */ }
public static class ManageApplicationsActivity extends SettingsActivity { /* empty */ }
+ public static class ManageAssistActivity extends SettingsActivity { /* empty */ }
public static class AllApplicationsActivity extends SettingsActivity { /* empty */ }
public static class HighPowerApplicationsActivity extends SettingsActivity { /* empty */ }
public static class AppOpsSummaryActivity extends SettingsActivity {
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index 3cef9ce..89231df 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -72,6 +72,7 @@ import com.android.settings.accounts.AccountSettings;
import com.android.settings.accounts.AccountSyncSettings;
import com.android.settings.applications.InstalledAppDetails;
import com.android.settings.applications.ManageApplications;
+import com.android.settings.applications.ManageAssist;
import com.android.settings.applications.ProcessStatsUi;
import com.android.settings.applications.UsageAccessDetails;
import com.android.settings.bluetooth.BluetoothSettings;
@@ -112,7 +113,6 @@ import com.android.settings.search.Index;
import com.android.settings.sim.SimSettings;
import com.android.settings.tts.TextToSpeechSettings;
import com.android.settings.users.UserSettings;
-import com.android.settings.voice.VoiceInputSettings;
import com.android.settings.vpn2.VpnSettings;
import com.android.settings.wfd.WifiDisplaySettings;
import com.android.settings.widget.SwitchBar;
@@ -290,7 +290,6 @@ public class SettingsActivity extends Activity
DateTimeSettings.class.getName(),
LocalePicker.class.getName(),
InputMethodAndLanguageSettings.class.getName(),
- VoiceInputSettings.class.getName(),
SpellCheckersSettings.class.getName(),
UserDictionaryList.class.getName(),
UserDictionarySettings.class.getName(),
@@ -298,6 +297,7 @@ public class SettingsActivity extends Activity
DisplaySettings.class.getName(),
DeviceInfoSettings.class.getName(),
ManageApplications.class.getName(),
+ ManageAssist.class.getName(),
ProcessStatsUi.class.getName(),
NotificationStation.class.getName(),
LocationSettings.class.getName(),
diff --git a/src/com/android/settings/VoiceInputOutputSettings.java b/src/com/android/settings/VoiceInputOutputSettings.java
index e052f8e..a264d50 100644
--- a/src/com/android/settings/VoiceInputOutputSettings.java
+++ b/src/com/android/settings/VoiceInputOutputSettings.java
@@ -31,7 +31,6 @@ public class VoiceInputOutputSettings {
private static final String TAG = "VoiceInputOutputSettings";
private static final String KEY_VOICE_CATEGORY = "voice_category";
- private static final String KEY_VOICE_INPUT_SETTINGS = "voice_input_settings";
private static final String KEY_TTS_SETTINGS = "tts_settings";
private PreferenceGroup mParent;
@@ -47,19 +46,16 @@ public class VoiceInputOutputSettings {
}
public void onCreate() {
-
mParent = mFragment.getPreferenceScreen();
mVoiceCategory = (PreferenceCategory) mParent.findPreference(KEY_VOICE_CATEGORY);
- mVoiceInputSettingsPref = mVoiceCategory.findPreference(KEY_VOICE_INPUT_SETTINGS);
mTtsSettingsPref = mVoiceCategory.findPreference(KEY_TTS_SETTINGS);
populateOrRemovePreferences();
}
private void populateOrRemovePreferences() {
- boolean hasVoiceInputPrefs = populateOrRemoveVoiceInputPrefs();
boolean hasTtsPrefs = populateOrRemoveTtsPrefs();
- if (!hasVoiceInputPrefs && !hasTtsPrefs) {
+ if (!hasTtsPrefs) {
// There were no TTS settings and no recognizer settings,
// so it should be safe to hide the preference category
// entirely.
@@ -67,16 +63,6 @@ public class VoiceInputOutputSettings {
}
}
- private boolean populateOrRemoveVoiceInputPrefs() {
- VoiceInputHelper helper = new VoiceInputHelper(mFragment.getActivity());
- if (!helper.hasItems()) {
- mVoiceCategory.removePreference(mVoiceInputSettingsPref);
- return false;
- }
-
- return true;
- }
-
private boolean populateOrRemoveTtsPrefs() {
if (mTtsEngines.getEngines().isEmpty()) {
mVoiceCategory.removePreference(mTtsSettingsPref);
diff --git a/src/com/android/settings/applications/DefaultAssistPreference.java b/src/com/android/settings/applications/DefaultAssistPreference.java
new file mode 100644
index 0000000..260d4b9
--- /dev/null
+++ b/src/com/android/settings/applications/DefaultAssistPreference.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2015 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.applications;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.provider.Settings;
+import android.service.voice.VoiceInteractionService;
+import android.service.voice.VoiceInteractionServiceInfo;
+import android.speech.RecognitionService;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.settings.AppListPreferenceWithSettings;
+import com.android.settings.R;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class DefaultAssistPreference extends AppListPreferenceWithSettings {
+
+ private static final String TAG = DefaultAssistPreference.class.getSimpleName();
+
+ private final List<Info> mAvailableAssistants = new ArrayList<>();
+
+ public DefaultAssistPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setShowItemNone(true);
+ setDialogTitle(R.string.choose_assist_title);
+ }
+
+ @Override
+ protected boolean persistString(String value) {
+ final Info info = findAssistantByPackageName(value);
+ if (info == null) {
+ setAssistNone();
+ return true;
+ }
+
+ if (info.isVoiceInteractionService()) {
+ setAssistService(info);
+ } else {
+ setAssistActivity(info);
+ }
+ return true;
+ }
+
+ private void setAssistNone() {
+ Settings.Secure.putString(getContext().getContentResolver(),
+ Settings.Secure.ASSISTANT, ITEM_NONE_VALUE);
+ Settings.Secure.putString(getContext().getContentResolver(),
+ Settings.Secure.VOICE_INTERACTION_SERVICE, "");
+ Settings.Secure.putString(getContext().getContentResolver(),
+ Settings.Secure.VOICE_RECOGNITION_SERVICE, getDefaultRecognizer());
+
+ setSummary(getContext().getText(R.string.default_assist_none));
+ setSettingsComponent(null);
+ }
+
+ private void setAssistService(Info serviceInfo) {
+ final String serviceComponentName = serviceInfo.component.flattenToShortString();
+ final String serviceRecognizerName = new ComponentName(
+ serviceInfo.component.getPackageName(),
+ serviceInfo.voiceInteractionServiceInfo.getRecognitionService())
+ .flattenToShortString();
+
+ Settings.Secure.putString(getContext().getContentResolver(),
+ Settings.Secure.ASSISTANT, serviceComponentName);
+ Settings.Secure.putString(getContext().getContentResolver(),
+ Settings.Secure.VOICE_INTERACTION_SERVICE, serviceComponentName);
+ Settings.Secure.putString(getContext().getContentResolver(),
+ Settings.Secure.VOICE_RECOGNITION_SERVICE, serviceRecognizerName);
+
+ setSummary(getEntry());
+ final String settingsActivity =
+ serviceInfo.voiceInteractionServiceInfo.getSettingsActivity();
+ setSettingsComponent(settingsActivity == null ?
+ null :
+ new ComponentName(serviceInfo.component.getPackageName(), settingsActivity));
+ }
+
+ private void setAssistActivity(Info activityInfo) {
+ Settings.Secure.putString(getContext().getContentResolver(),
+ Settings.Secure.ASSISTANT, activityInfo.component.flattenToShortString());
+ Settings.Secure.putString(getContext().getContentResolver(),
+ Settings.Secure.VOICE_INTERACTION_SERVICE, "");
+ Settings.Secure.putString(getContext().getContentResolver(),
+ Settings.Secure.VOICE_RECOGNITION_SERVICE, getDefaultRecognizer());
+
+ setSummary(getEntry());
+ setSettingsComponent(null);
+ }
+
+ private String getDefaultRecognizer() {
+ ResolveInfo resolveInfo = getContext().getPackageManager().resolveService(
+ new Intent(RecognitionService.SERVICE_INTERFACE),
+ PackageManager.GET_META_DATA);
+ if (resolveInfo == null || resolveInfo.serviceInfo == null) {
+ Log.w(TAG, "Unable to resolve default voice recognition service.");
+ return "";
+ }
+
+ return new ComponentName(resolveInfo.serviceInfo.packageName,
+ resolveInfo.serviceInfo.name).flattenToShortString();
+ }
+
+ private Info findAssistantByPackageName(String packageName) {
+ for (int i = 0; i < mAvailableAssistants.size(); ++i) {
+ Info info = mAvailableAssistants.get(i);
+ if (info.component.getPackageName().equals(packageName)) {
+ return info;
+ }
+ }
+ return null;
+ }
+
+ private void addAssistServices() {
+ PackageManager pm = getContext().getPackageManager();
+
+ List<ResolveInfo> services = pm.queryIntentServices(
+ new Intent(VoiceInteractionService.SERVICE_INTERFACE),
+ PackageManager.GET_META_DATA);
+ for (int i = 0; i < services.size(); ++i) {
+ ResolveInfo resolveInfo = services.get(i);
+ VoiceInteractionServiceInfo voiceInteractionServiceInfo =
+ new VoiceInteractionServiceInfo(pm, resolveInfo.serviceInfo);
+ if (!voiceInteractionServiceInfo.getSupportsAssist()) {
+ continue;
+ }
+
+ mAvailableAssistants.add(new Info(
+ new ComponentName(resolveInfo.serviceInfo.packageName,
+ resolveInfo.serviceInfo.name),
+ voiceInteractionServiceInfo));
+ }
+ }
+
+ private void addAssistActivities() {
+ PackageManager pm = getContext().getPackageManager();
+
+ List<ResolveInfo> activities = pm.queryIntentActivities(
+ new Intent(Intent.ACTION_ASSIST),
+ PackageManager.MATCH_DEFAULT_ONLY);
+ for (int i = 0; i < activities.size(); ++i) {
+ ResolveInfo resolveInfo = activities.get(i);
+ mAvailableAssistants.add(new Info(
+ new ComponentName(resolveInfo.activityInfo.packageName,
+ resolveInfo.activityInfo.name)));
+ }
+ }
+
+ public ComponentName getCurrentAssist() {
+ String currentSetting = Settings.Secure.getString(getContext().getContentResolver(),
+ Settings.Secure.ASSISTANT);
+ return currentSetting == null ? null : ComponentName.unflattenFromString(currentSetting);
+ }
+
+ public void refreshAssistApps() {
+ mAvailableAssistants.clear();
+ addAssistServices();
+ addAssistActivities();
+
+ List<String> packages = new ArrayList<>();
+ for (int i = 0; i < mAvailableAssistants.size(); ++i) {
+ String packageName = mAvailableAssistants.get(i).component.getPackageName();
+ if (packages.contains(packageName)) {
+ // A service appears before an activity thus overrides it if from the same package.
+ continue;
+ }
+ packages.add(packageName);
+ }
+
+ ComponentName currentAssist = getCurrentAssist();
+ setPackageNames(packages.toArray(new String[packages.size()]),
+ currentAssist == null ? null : currentAssist.getPackageName());
+ }
+
+ private static class Info {
+ public final ComponentName component;
+ public final VoiceInteractionServiceInfo voiceInteractionServiceInfo;
+
+ Info(ComponentName component) {
+ this.component = component;
+ this.voiceInteractionServiceInfo = null;
+ }
+
+ Info(ComponentName component, VoiceInteractionServiceInfo voiceInteractionServiceInfo) {
+ this.component = component;
+ this.voiceInteractionServiceInfo = voiceInteractionServiceInfo;
+ }
+
+ public boolean isVoiceInteractionService() {
+ return voiceInteractionServiceInfo != null;
+ }
+ }
+}
diff --git a/src/com/android/settings/applications/ManageAssist.java b/src/com/android/settings/applications/ManageAssist.java
index d3bc0c8..f937811 100644
--- a/src/com/android/settings/applications/ManageAssist.java
+++ b/src/com/android/settings/applications/ManageAssist.java
@@ -16,6 +16,9 @@
package com.android.settings.applications;
+import android.app.AlertDialog;
+import android.content.ComponentName;
+import android.content.DialogInterface;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.SwitchPreference;
@@ -25,6 +28,7 @@ import com.android.internal.logging.MetricsLogger;
import com.android.settings.InstrumentedFragment;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.voice.VoiceInputListPreference;
/**
* Settings screen to manage everything about assist.
@@ -32,18 +36,29 @@ import com.android.settings.SettingsPreferenceFragment;
public class ManageAssist extends SettingsPreferenceFragment
implements Preference.OnPreferenceChangeListener {
+ private static final String KEY_DEFAULT_ASSIST = "default_assist";
private static final String KEY_CONTEXT = "context";
+ private static final String KEY_VOICE_INPUT = "voice_input_settings";
+ private DefaultAssistPreference mDefaultAssitPref;
private SwitchPreference mContextPref;
+ private VoiceInputListPreference mVoiceInputPref;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
addPreferencesFromResource(R.xml.manage_assist);
+
+ mDefaultAssitPref = (DefaultAssistPreference) findPreference(KEY_DEFAULT_ASSIST);
+ mDefaultAssitPref.setOnPreferenceChangeListener(this);
+
mContextPref = (SwitchPreference) findPreference(KEY_CONTEXT);
mContextPref.setChecked(Settings.Secure.getInt(getContentResolver(),
Settings.Secure.ASSIST_STRUCTURE_ENABLED, 1) != 0);
mContextPref.setOnPreferenceChangeListener(this);
+
+ mVoiceInputPref = (VoiceInputListPreference) findPreference(KEY_VOICE_INPUT);
+ updateUi();
}
@Override
@@ -58,6 +73,64 @@ public class ManageAssist extends SettingsPreferenceFragment
(boolean) newValue ? 1 : 0);
return true;
}
+ if (preference == mDefaultAssitPref) {
+ String newAssitPackage = (String)newValue;
+ if (newAssitPackage == null ||
+ newAssitPackage.contentEquals(DefaultAssistPreference.ITEM_NONE_VALUE)) {
+ setDefaultAssist(DefaultAssistPreference.ITEM_NONE_VALUE);
+ return false;
+ }
+
+ final String currentPackage = mDefaultAssitPref.getValue();
+ if (currentPackage == null || !newAssitPackage.contentEquals(currentPackage)) {
+ confirmNewAssist(newAssitPackage);
+ }
+ return false;
+ }
return false;
}
+
+ private void updateUi() {
+ mDefaultAssitPref.refreshAssistApps();
+
+ final ComponentName currentAssist = mDefaultAssitPref.getCurrentAssist();
+ final boolean hasAssistant = currentAssist != null;
+ if (hasAssistant) {
+ getPreferenceScreen().addPreference(mContextPref);
+ } else {
+ getPreferenceScreen().removePreference(mContextPref);
+ }
+
+ mVoiceInputPref.setAssistRestrict(currentAssist);
+ mVoiceInputPref.refreshVoiceInputs();
+ }
+
+ private void confirmNewAssist(final String newAssitPackage) {
+ final int selected = mDefaultAssitPref.findIndexOfValue(newAssitPackage);
+ final CharSequence appLabel = mDefaultAssitPref.getEntries()[selected];
+
+ final String title = getString(R.string.assistant_security_warning_title, appLabel);
+ final String message = getString(R.string.assistant_security_warning, appLabel);
+
+ final DialogInterface.OnClickListener onAgree = new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ setDefaultAssist(newAssitPackage);
+ }
+ };
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
+ builder.setTitle(title)
+ .setMessage(message)
+ .setCancelable(true)
+ .setPositiveButton(R.string.assistant_security_warning_agree, onAgree)
+ .setNegativeButton(R.string.assistant_security_warning_disagree, null);
+ AlertDialog dialog = builder.create();
+ dialog.show();
+ }
+
+ private void setDefaultAssist(String assistPackage) {
+ mDefaultAssitPref.setValue(assistPackage);
+ updateUi();
+ }
}
diff --git a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
index 8f23ce9..93ece66 100644
--- a/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
+++ b/src/com/android/settings/inputmethod/InputMethodAndLanguageSettings.java
@@ -790,14 +790,6 @@ public class InputMethodAndLanguageSettings extends SettingsPreferenceFragment
indexables.add(indexable);
}
- // Voice input
- indexable = new SearchIndexableRaw(context);
- indexable.key = "voice_input_settings";
- indexable.title = context.getString(R.string.voice_input_settings);
- indexable.screenTitle = screenTitle;
- indexable.keywords = context.getString(R.string.keywords_voice_input);
- indexables.add(indexable);
-
// Text-to-speech.
TtsEngines ttsEngines = new TtsEngines(context);
if (!ttsEngines.getEngines().isEmpty()) {
diff --git a/src/com/android/settings/search/Ranking.java b/src/com/android/settings/search/Ranking.java
index 6481aba..3edfee7 100644
--- a/src/com/android/settings/search/Ranking.java
+++ b/src/com/android/settings/search/Ranking.java
@@ -49,7 +49,6 @@ import com.android.settings.notification.ZenModeSettings;
import com.android.settings.print.PrintSettingsFragment;
import com.android.settings.sim.SimSettings;
import com.android.settings.users.UserSettings;
-import com.android.settings.voice.VoiceInputSettings;
import com.android.settings.wifi.AdvancedWifiSettings;
import com.android.settings.wifi.SavedAccessPointsWifiSettings;
import com.android.settings.wifi.WifiSettings;
@@ -154,7 +153,6 @@ public final class Ranking {
// IMEs
sRankMap.put(InputMethodAndLanguageSettings.class.getName(), RANK_IME);
- sRankMap.put(VoiceInputSettings.class.getName(), RANK_IME);
// Privacy
sRankMap.put(PrivacySettings.class.getName(), RANK_PRIVACY);
diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java
index 7cb0dd1..f3c0b42 100644
--- a/src/com/android/settings/search/SearchIndexableResources.java
+++ b/src/com/android/settings/search/SearchIndexableResources.java
@@ -50,7 +50,6 @@ import com.android.settings.notification.ZenModeSettings;
import com.android.settings.print.PrintSettingsFragment;
import com.android.settings.sim.SimSettings;
import com.android.settings.users.UserSettings;
-import com.android.settings.voice.VoiceInputSettings;
import com.android.settings.wifi.AdvancedWifiSettings;
import com.android.settings.wifi.SavedAccessPointsWifiSettings;
import com.android.settings.wifi.WifiSettings;
@@ -248,13 +247,6 @@ public final class SearchIndexableResources {
InputMethodAndLanguageSettings.class.getName(),
R.drawable.ic_settings_language));
- sResMap.put(VoiceInputSettings.class.getName(),
- new SearchIndexableResource(
- Ranking.getRankForClassName(VoiceInputSettings.class.getName()),
- NO_DATA_RES_ID,
- VoiceInputSettings.class.getName(),
- R.drawable.ic_settings_language));
-
sResMap.put(PrivacySettings.class.getName(),
new SearchIndexableResource(
Ranking.getRankForClassName(PrivacySettings.class.getName()),
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;
- }
- };
-}