Deprecate AppListPreference and AppListPrefWithSettings
- Convert ManageAssist into DashboardFragment
- Convert default assist pref to DefaultAppPickerFragment
- Add PreferenceController for each pref
- Add tests
Bug: 35203386
Test: make RunSettingsRoboTests
Change-Id: I0350a06cae7457809fb261e2d8ec99eda80cc50a
diff --git a/src/com/android/settings/AppListPreference.java b/src/com/android/settings/AppListPreference.java
deleted file mode 100644
index 8585454..0000000
--- a/src/com/android/settings/AppListPreference.java
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * Copyright (C) 2013 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;
-
-import android.app.AlertDialog;
-import android.app.AppGlobals;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.pm.ActivityInfo;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.TypedArray;
-import android.graphics.drawable.Drawable;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.text.TextUtils;
-import android.util.AttributeSet;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-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.
- *
- * @deprecated Selecting app from a list should be done in full UI. Use DefaultAppPickerFragment
- * instead.
- */
-@Deprecated
-public class AppListPreference extends CustomListPreference {
-
- public static final String ITEM_NONE_VALUE = "";
-
- protected final boolean mForWork;
- protected final int mUserId;
-
-
- private boolean mSavesState = true;
- private Drawable[] mEntryDrawables;
- private boolean mShowItemNone = false;
- private CharSequence[] mSummaries;
- private int mSystemAppIndex = -1;
-
- public class AppArrayAdapter extends ArrayAdapter<CharSequence> {
- private Drawable[] mImageDrawables = null;
- private int mSelectedIndex = 0;
-
- public AppArrayAdapter(Context context, int textViewResourceId,
- CharSequence[] objects, Drawable[] imageDrawables, int selectedIndex) {
- super(context, textViewResourceId, objects);
- mSelectedIndex = selectedIndex;
- mImageDrawables = imageDrawables;
- }
-
- @Override
- public boolean isEnabled(int position) {
- return mSummaries == null || mSummaries[position] == null;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- LayoutInflater inflater = LayoutInflater.from(getContext());
- View view = inflater.inflate(R.layout.app_preference_item, parent, false);
- TextView textView = (TextView) view.findViewById(android.R.id.title);
- textView.setText(getItem(position));
- if (position == mSelectedIndex && position == mSystemAppIndex) {
- view.findViewById(R.id.system_default_label).setVisibility(View.VISIBLE);
- } else if (position == mSelectedIndex) {
- view.findViewById(R.id.default_label).setVisibility(View.VISIBLE);
- } else if (position == mSystemAppIndex) {
- view.findViewById(R.id.system_label).setVisibility(View.VISIBLE);
- }
- ImageView imageView = (ImageView) view.findViewById(android.R.id.icon);
- imageView.setImageDrawable(mImageDrawables[position]);
- // Summaries are describing why a item is disabled, so anything with a summary
- // is not enabled.
- boolean enabled = mSummaries == null || mSummaries[position] == null;
- view.setEnabled(enabled);
- if (!enabled) {
- TextView summary = (TextView) view.findViewById(android.R.id.summary);
- summary.setText(mSummaries[position]);
- summary.setVisibility(View.VISIBLE);
- }
- return view;
- }
- }
-
- public AppListPreference(Context context, AttributeSet attrs, int defStyle, int defAttrs) {
- super(context, attrs, defStyle, defAttrs);
-
- TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.WorkPreference, 0, 0);
- mForWork = a.getBoolean(R.styleable.WorkPreference_forWork, false);
- final UserHandle managedProfile = Utils.getManagedProfile(UserManager.get(context));
- mUserId = mForWork && managedProfile != null ? managedProfile.getIdentifier()
- : UserHandle.myUserId();
- }
-
- public AppListPreference(Context context, AttributeSet attrs) {
- super(context, attrs);
-
- TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.WorkPreference, 0, 0);
- mForWork = a.getBoolean(R.styleable.WorkPreference_forWork, false);
- final UserHandle managedProfile = Utils.getManagedProfile(UserManager.get(context));
- mUserId = mForWork && managedProfile != null ? managedProfile.getIdentifier()
- : UserHandle.myUserId();
- }
-
- public void setSavesState(boolean savesState) {
- mSavesState = savesState;
- }
-
- public void setShowItemNone(boolean showItemNone) {
- mShowItemNone = showItemNone;
- }
-
- public void setPackageNames(CharSequence[] packageNames, CharSequence defaultPackageName) {
- setPackageNames(packageNames, defaultPackageName, null);
- }
-
- public void setPackageNames(CharSequence[] packageNames, CharSequence defaultPackageName,
- CharSequence systemPackageName) {
- // Look up all package names in PackageManager. Skip ones we can't find.
- PackageManager pm = getContext().getPackageManager();
- 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;
- mSystemAppIndex = -1;
- for (int i = 0; i < packageNames.length; i++) {
- try {
- ApplicationInfo appInfo = pm.getApplicationInfoAsUser(packageNames[i].toString(), 0,
- mUserId);
- applicationNames.add(appInfo.loadLabel(pm));
- validatedPackageNames.add(appInfo.packageName);
- entryDrawables.add(appInfo.loadIcon(pm));
- if (defaultPackageName != null &&
- appInfo.packageName.contentEquals(defaultPackageName)) {
- selectedIndex = i;
- }
- if (appInfo.packageName != null && systemPackageName != null &&
- appInfo.packageName.contentEquals(systemPackageName)) {
- mSystemAppIndex = i;
- }
- } catch (NameNotFoundException e) {
- // Skip unknown packages.
- }
- }
-
- 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 {
- setValue(null);
- }
- }
-
- public void setComponentNames(ComponentName[] componentNames, ComponentName defaultCN) {
- setComponentNames(componentNames, defaultCN, null);
- }
-
- public void setComponentNames(ComponentName[] componentNames, ComponentName defaultCN,
- CharSequence[] summaries) {
- mSummaries = summaries;
- // Look up all package names in PackageManager. Skip ones we can't find.
- PackageManager pm = getContext().getPackageManager();
- final int entryCount = componentNames.length + (mShowItemNone ? 1 : 0);
- List<CharSequence> applicationNames = new ArrayList<>(entryCount);
- List<CharSequence> validatedComponentNames = new ArrayList<>(entryCount);
- List<Drawable> entryDrawables = new ArrayList<>(entryCount);
- int selectedIndex = -1;
- for (int i = 0; i < componentNames.length; i++) {
- try {
- ActivityInfo activityInfo = AppGlobals.getPackageManager().getActivityInfo(
- componentNames[i], 0, mUserId);
- if (activityInfo != null) {
- applicationNames.add(activityInfo.loadLabel(pm));
- validatedComponentNames.add(componentNames[i].flattenToString());
- entryDrawables.add(activityInfo.loadIcon(pm));
- } else {
- ApplicationInfo appInfo = pm.getApplicationInfoAsUser(
- componentNames[i].getPackageName().toString(), 0, mUserId);
- applicationNames.add(appInfo.loadLabel(pm));
- validatedComponentNames.add(componentNames[i].flattenToString());
- entryDrawables.add(appInfo.loadIcon(pm));
- }
- if (defaultCN != null && componentNames[i].equals(defaultCN)) {
- selectedIndex = i;
- }
- } catch (RemoteException|NameNotFoundException e) {
- // Skip unknown packages.
- }
- }
-
- if (mShowItemNone) {
- applicationNames.add(
- getContext().getResources().getText(R.string.app_list_preference_none));
- validatedComponentNames.add(ITEM_NONE_VALUE);
- entryDrawables.add(getContext().getDrawable(R.drawable.ic_remove_circle));
- }
-
- setEntries(applicationNames.toArray(new CharSequence[applicationNames.size()]));
- setEntryValues(
- validatedComponentNames.toArray(new CharSequence[validatedComponentNames.size()]));
- mEntryDrawables = entryDrawables.toArray(new Drawable[entryDrawables.size()]);
-
- if (selectedIndex != -1) {
- setValueIndex(selectedIndex);
- } else {
- setValue(null);
- }
- }
-
- 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(AlertDialog.Builder builder,
- DialogInterface.OnClickListener listener) {
- builder.setAdapter(createListAdapter(), listener);
- }
-
- @Override
- protected Parcelable onSaveInstanceState() {
- Parcelable superState = super.onSaveInstanceState();
- if (mSavesState) {
- return new SavedState(getEntryValues(), getValue(), mSummaries, mShowItemNone, superState);
- } else {
- return superState;
- }
- }
-
- @Override
- protected void onRestoreInstanceState(Parcelable state) {
- if (mSavesState || state instanceof SavedState) {
- SavedState savedState = (SavedState) state;
- mShowItemNone = savedState.showItemNone;
- setPackageNames(savedState.entryValues, savedState.value);
- mSummaries = savedState.summaries;
- super.onRestoreInstanceState(savedState.superState);
- } else {
- super.onRestoreInstanceState(state);
- }
- }
-
- /**
- * Sets app label as summary if there is only 1 app applicable to this preference.
- */
- protected void setSoleAppLabelAsSummary() {
- final CharSequence soleLauncherLabel = getSoleAppLabel();
- if (!TextUtils.isEmpty(soleLauncherLabel)) {
- setSummary(soleLauncherLabel);
- }
- }
-
- /**
- * Returns app label if there is only 1 app applicable to this preference.
- */
- protected CharSequence getSoleAppLabel() {
- // Intentionally left empty so subclasses can override with necessary logic.
- return null;
- }
-
- private static class SavedState implements Parcelable {
-
- public final CharSequence[] entryValues;
- public final CharSequence value;
- public final boolean showItemNone;
- public final Parcelable superState;
- public final CharSequence[] summaries;
-
- public SavedState(CharSequence[] entryValues, CharSequence value, CharSequence[] summaries,
- boolean showItemNone, Parcelable superState) {
- this.entryValues = entryValues;
- this.value = value;
- this.showItemNone = showItemNone;
- this.superState = superState;
- this.summaries = summaries;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeCharSequenceArray(entryValues);
- dest.writeCharSequence(value);
- dest.writeInt(showItemNone ? 1 : 0);
- dest.writeParcelable(superState, flags);
- dest.writeCharSequenceArray(summaries);
- }
-
- public static Creator<SavedState> CREATOR = new Creator<SavedState>() {
- @Override
- public SavedState createFromParcel(Parcel source) {
- CharSequence[] entryValues = source.readCharSequenceArray();
- CharSequence value = source.readCharSequence();
- boolean showItemNone = source.readInt() != 0;
- Parcelable superState = source.readParcelable(getClass().getClassLoader());
- CharSequence[] summaries = source.readCharSequenceArray();
- return new SavedState(entryValues, value, summaries, showItemNone, superState);
- }
-
- @Override
- public SavedState[] newArray(int size) {
- return new SavedState[size];
- }
- };
- }
-}
diff --git a/src/com/android/settings/AppListPreferenceWithSettings.java b/src/com/android/settings/AppListPreferenceWithSettings.java
deleted file mode 100644
index a499a7b..0000000
--- a/src/com/android/settings/AppListPreferenceWithSettings.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package com.android.settings;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.support.v7.preference.PreferenceViewHolder;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewGroup;
-
-/**
- * An AppListPreference with optional settings button.
- */
-@Deprecated
-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
- public void onBindViewHolder(PreferenceViewHolder view) {
- super.onBindViewHolder(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/applications/ManageAssist.java b/src/com/android/settings/applications/ManageAssist.java
deleted file mode 100644
index 8dd4d70..0000000
--- a/src/com/android/settings/applications/ManageAssist.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * 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.app.AlertDialog;
-import android.content.ComponentName;
-import android.content.DialogInterface;
-import android.os.Bundle;
-import android.os.Handler;
-import android.provider.Settings;
-import android.support.v14.preference.SwitchPreference;
-import android.support.v7.preference.Preference;
-
-import com.android.internal.app.AssistUtils;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.settings.R;
-import com.android.settings.SettingsPreferenceFragment;
-import com.android.settings.gestures.AssistGestureFeatureProvider;
-import com.android.settings.overlay.FeatureFactory;
-import com.android.settings.voice.VoiceInputListPreference;
-
-/**
- * Settings screen to manage everything about assist.
- */
-public class ManageAssist extends SettingsPreferenceFragment
- implements Preference.OnPreferenceChangeListener {
-
- private static final String KEY_DEFAULT_ASSIST = "default_assist";
- private static final String KEY_ASSIST_GESTURE = "gesture_assist";
- private static final String KEY_CONTEXT = "context";
- private static final String KEY_SCREENSHOT = "screenshot";
- private static final String KEY_VOICE_INPUT = "voice_input_settings";
- private static final String KEY_FLASH = "flash";
-
- private DefaultAssistPreference mDefaultAssitPref;
- private SwitchPreference mContextPref;
- private SwitchPreference mScreenshotPref;
- private SwitchPreference mFlashPref;
- private VoiceInputListPreference mVoiceInputPref;
- private Handler mHandler = new Handler();
-
- private Preference mAssistGesturePref;
- private AssistGestureFeatureProvider mAssistGestureFeatureProvider;
-
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
- addPreferencesFromResource(R.xml.manage_assist);
-
- mDefaultAssitPref = (DefaultAssistPreference) findPreference(KEY_DEFAULT_ASSIST);
- mDefaultAssitPref.setOnPreferenceChangeListener(this);
-
- mAssistGesturePref = findPreference(KEY_ASSIST_GESTURE);
- mAssistGestureFeatureProvider =
- FeatureFactory.getFactory(getContext()).getAssistGestureFeatureProvider();
-
- mContextPref = (SwitchPreference) findPreference(KEY_CONTEXT);
- mContextPref.setChecked(Settings.Secure.getInt(getContentResolver(),
- Settings.Secure.ASSIST_STRUCTURE_ENABLED, 1) != 0);
- mContextPref.setOnPreferenceChangeListener(this);
-
- mScreenshotPref = (SwitchPreference) findPreference(KEY_SCREENSHOT);
- mScreenshotPref.setOnPreferenceChangeListener(this);
-
- mFlashPref = (SwitchPreference) findPreference(KEY_FLASH);
- mFlashPref.setOnPreferenceChangeListener(this);
- mFooterPreferenceMixin.createFooterPreference()
- .setTitle(R.string.assist_footer);
- mVoiceInputPref = (VoiceInputListPreference) findPreference(KEY_VOICE_INPUT);
- updateUi();
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsEvent.APPLICATIONS_MANAGE_ASSIST;
- }
-
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (preference == mContextPref) {
- Settings.Secure.putInt(getContentResolver(), Settings.Secure.ASSIST_STRUCTURE_ENABLED,
- (boolean) newValue ? 1 : 0);
- mHandler.post(() -> {
- guardFlashPref();
- });
- return true;
- }
- if (preference == mScreenshotPref) {
- Settings.Secure.putInt(getContentResolver(), Settings.Secure.ASSIST_SCREENSHOT_ENABLED,
- (boolean) newValue ? 1 : 0);
- return true;
- }
- if (preference == mFlashPref) {
- Settings.Secure.putInt(getContentResolver(), Settings.Secure.ASSIST_DISCLOSURE_ENABLED,
- (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 guardFlashPref() {
- ComponentName assistant = mDefaultAssitPref.getCurrentAssist();
-
- boolean isContextChecked = mContextPref.isChecked();
- boolean willShowFlash = AssistUtils.shouldDisclose(getContext(), assistant);
- boolean isSystemAssistant = AssistUtils.isPreinstalledAssistant(getContext(), assistant);
-
- mFlashPref.setEnabled(isContextChecked && isSystemAssistant);
- mFlashPref.setChecked(willShowFlash);
- }
-
- private void updateUi() {
- mDefaultAssitPref.refreshAssistApps();
- mVoiceInputPref.refreshVoiceInputs();
-
- final ComponentName currentAssist = mDefaultAssitPref.getCurrentAssist();
- final boolean hasAssistant = currentAssist != null;
- if (hasAssistant) {
- getPreferenceScreen().addPreference(mContextPref);
- getPreferenceScreen().addPreference(mScreenshotPref);
- } else {
- getPreferenceScreen().removePreference(mContextPref);
- getPreferenceScreen().removePreference(mScreenshotPref);
- getPreferenceScreen().removePreference(mFlashPref);
- }
-
- if (hasAssistant && mAssistGestureFeatureProvider.isSupported(getContext())) {
- getPreferenceScreen().addPreference(mAssistGesturePref);
- } else {
- getPreferenceScreen().removePreference(mAssistGesturePref);
- }
-
- if (hasAssistant && AssistUtils.allowDisablingAssistDisclosure(getContext())) {
- getPreferenceScreen().addPreference(mFlashPref);
- } else {
- getPreferenceScreen().removePreference(mFlashPref);
- }
-
- if (isCurrentAssistVoiceService()) {
- getPreferenceScreen().removePreference(mVoiceInputPref);
- } else {
- getPreferenceScreen().addPreference(mVoiceInputPref);
- mVoiceInputPref.setAssistRestrict(currentAssist);
- }
-
- guardFlashPref();
- }
-
- private boolean isCurrentAssistVoiceService() {
- ComponentName currentAssist = mDefaultAssitPref.getCurrentAssist();
- ComponentName activeService = mVoiceInputPref.getCurrentService();
- return currentAssist == null && activeService == null ||
- currentAssist != null && currentAssist.equals(activeService);
- }
-
- 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/applications/assist/AssistContextPreferenceController.java b/src/com/android/settings/applications/assist/AssistContextPreferenceController.java
new file mode 100644
index 0000000..05bc8d6
--- /dev/null
+++ b/src/com/android/settings/applications/assist/AssistContextPreferenceController.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2017 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.assist;
+
+import android.content.Context;
+import android.net.Uri;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.support.v7.preference.TwoStatePreference;
+
+import com.android.internal.app.AssistUtils;
+import com.android.settings.core.PreferenceController;
+import com.android.settings.core.lifecycle.Lifecycle;
+import com.android.settings.core.lifecycle.LifecycleObserver;
+import com.android.settings.core.lifecycle.events.OnPause;
+import com.android.settings.core.lifecycle.events.OnResume;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class AssistContextPreferenceController extends PreferenceController
+ implements Preference.OnPreferenceChangeListener, LifecycleObserver, OnResume, OnPause {
+
+ private static final String KEY_CONTEXT = "context";
+
+ private final AssistUtils mAssistUtils;
+ private final SettingObserver mSettingObserver;
+
+ private Preference mPreference;
+ private PreferenceScreen mScreen;
+
+ public AssistContextPreferenceController(Context context, Lifecycle lifecycle) {
+ super(context);
+ mAssistUtils = new AssistUtils(context);
+ mSettingObserver = new SettingObserver();
+
+ if (lifecycle != null) {
+ lifecycle.addObserver(this);
+ }
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return mAssistUtils.getAssistComponentForUser(UserHandle.myUserId()) != null;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_CONTEXT;
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ mScreen = screen;
+ mPreference = screen.findPreference(getPreferenceKey());
+ super.displayPreference(screen);
+ }
+
+ @Override
+ public void onResume() {
+ mSettingObserver.register(mContext.getContentResolver(), true);
+ updatePreference();
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ updatePreference();
+ }
+
+ @Override
+ public void onPause() {
+ mSettingObserver.register(mContext.getContentResolver(), false);
+ }
+
+
+ private void updatePreference() {
+ if (mPreference == null || !(mPreference instanceof TwoStatePreference)) {
+ return;
+ }
+ if (isAvailable()) {
+ if (mScreen.findPreference(getPreferenceKey()) == null) {
+ // add it if it's not on scree
+ mScreen.addPreference(mPreference);
+ }
+ } else {
+ mScreen.removePreference(mPreference);
+ }
+
+ ((TwoStatePreference) mPreference).setChecked(isChecked(mContext));
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.ASSIST_STRUCTURE_ENABLED,
+ (boolean) newValue ? 1 : 0);
+ return true;
+ }
+
+ static boolean isChecked(Context context) {
+ return Settings.Secure.getInt(context.getContentResolver(),
+ Settings.Secure.ASSIST_STRUCTURE_ENABLED, 1) != 0;
+ }
+
+ class SettingObserver extends AssistSettingObserver {
+
+ private final Uri URI =
+ Settings.Secure.getUriFor(Settings.Secure.ASSIST_STRUCTURE_ENABLED);
+
+ @Override
+ protected List<Uri> getSettingUris() {
+ return Arrays.asList(URI);
+ }
+
+ @Override
+ public void onSettingChange() {
+ updatePreference();
+ }
+ }
+}
diff --git a/src/com/android/settings/applications/assist/AssistFlashScreenPreferenceController.java b/src/com/android/settings/applications/assist/AssistFlashScreenPreferenceController.java
new file mode 100644
index 0000000..e44e70f
--- /dev/null
+++ b/src/com/android/settings/applications/assist/AssistFlashScreenPreferenceController.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2017 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.assist;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.net.Uri;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.support.v7.preference.TwoStatePreference;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.app.AssistUtils;
+import com.android.settings.core.PreferenceController;
+import com.android.settings.core.lifecycle.Lifecycle;
+import com.android.settings.core.lifecycle.LifecycleObserver;
+import com.android.settings.core.lifecycle.events.OnPause;
+import com.android.settings.core.lifecycle.events.OnResume;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class AssistFlashScreenPreferenceController extends PreferenceController
+ implements Preference.OnPreferenceChangeListener, LifecycleObserver, OnResume, OnPause {
+
+ private static final String KEY_FLASH = "flash";
+
+ private final AssistUtils mAssistUtils;
+ private final SettingObserver mSettingObserver;
+ private PreferenceScreen mScreen;
+ private Preference mPreference;
+
+ public AssistFlashScreenPreferenceController(Context context, Lifecycle lifecycle) {
+ super(context);
+ mAssistUtils = new AssistUtils(context);
+ mSettingObserver = new SettingObserver();
+
+ if (lifecycle != null) {
+ lifecycle.addObserver(this);
+ }
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return getCurrentAssist() != null && allowDisablingAssistDisclosure();
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_FLASH;
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ mScreen = screen;
+ mPreference = screen.findPreference(getPreferenceKey());
+ super.displayPreference(screen);
+ }
+
+ @Override
+ public void onResume() {
+ mSettingObserver.register(mContext.getContentResolver(), true);
+ updatePreference();
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ updatePreference();
+ }
+
+ @Override
+ public void onPause() {
+ mSettingObserver.register(mContext.getContentResolver(), false);
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.ASSIST_DISCLOSURE_ENABLED,
+ (boolean) newValue ? 1 : 0);
+ return true;
+ }
+
+ private void updatePreference() {
+ if (mPreference == null || !(mPreference instanceof TwoStatePreference)) {
+ return;
+ }
+ if (isAvailable()) {
+ if (mScreen.findPreference(getPreferenceKey()) == null) {
+ // add it if it's not on scree
+ mScreen.addPreference(mPreference);
+ }
+ } else {
+ mScreen.removePreference(mPreference);
+ }
+ ComponentName assistant = getCurrentAssist();
+
+ boolean isContextChecked = AssistContextPreferenceController.isChecked(mContext);
+
+ mPreference.setEnabled(isContextChecked && isPreInstalledAssistant(assistant));
+ ((TwoStatePreference) mPreference).setChecked(willShowFlash(assistant));
+ }
+
+ @VisibleForTesting
+ boolean willShowFlash(ComponentName assistant) {
+ return AssistUtils.shouldDisclose(mContext, assistant);
+ }
+
+ @VisibleForTesting
+ boolean isPreInstalledAssistant(ComponentName assistant) {
+ return AssistUtils.isPreinstalledAssistant(mContext, assistant);
+ }
+
+ @VisibleForTesting
+ boolean allowDisablingAssistDisclosure() {
+ return AssistUtils.allowDisablingAssistDisclosure(mContext);
+ }
+
+ private ComponentName getCurrentAssist() {
+ return mAssistUtils.getAssistComponentForUser(UserHandle.myUserId());
+ }
+
+ class SettingObserver extends AssistSettingObserver {
+
+ private final Uri URI =
+ Settings.Secure.getUriFor(Settings.Secure.ASSIST_DISCLOSURE_ENABLED);
+ private final Uri CONTEXT_URI =
+ Settings.Secure.getUriFor(Settings.Secure.ASSIST_STRUCTURE_ENABLED);
+
+ @Override
+ protected List<Uri> getSettingUris() {
+ return Arrays.asList(URI, CONTEXT_URI);
+ }
+
+ @Override
+ public void onSettingChange() {
+ updatePreference();
+ }
+ }
+
+
+}
diff --git a/src/com/android/settings/applications/assist/AssistScreenshotPreferenceController.java b/src/com/android/settings/applications/assist/AssistScreenshotPreferenceController.java
new file mode 100644
index 0000000..21dfe19
--- /dev/null
+++ b/src/com/android/settings/applications/assist/AssistScreenshotPreferenceController.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2017 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.assist;
+
+import android.content.Context;
+import android.net.Uri;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.support.v7.preference.TwoStatePreference;
+
+import com.android.internal.app.AssistUtils;
+import com.android.settings.core.PreferenceController;
+import com.android.settings.core.lifecycle.Lifecycle;
+import com.android.settings.core.lifecycle.LifecycleObserver;
+import com.android.settings.core.lifecycle.events.OnPause;
+import com.android.settings.core.lifecycle.events.OnResume;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class AssistScreenshotPreferenceController extends PreferenceController
+ implements Preference.OnPreferenceChangeListener, LifecycleObserver, OnResume, OnPause {
+
+ private static final String KEY_SCREENSHOT = "screenshot";
+
+ private final AssistUtils mAssistUtils;
+ private final SettingObserver mSettingObserver;
+
+ private PreferenceScreen mScreen;
+ private Preference mPreference;
+
+ public AssistScreenshotPreferenceController(Context context, Lifecycle lifecycle) {
+ super(context);
+ mAssistUtils = new AssistUtils(context);
+ mSettingObserver = new SettingObserver();
+ if (lifecycle != null) {
+ lifecycle.addObserver(this);
+ }
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return mAssistUtils.getAssistComponentForUser(UserHandle.myUserId()) != null;
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ mScreen = screen;
+ mPreference = screen.findPreference(getPreferenceKey());
+ super.displayPreference(screen);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_SCREENSHOT;
+ }
+
+ @Override
+ public void onResume() {
+ mSettingObserver.register(mContext.getContentResolver(), true);
+ updatePreference();
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ updatePreference();
+ }
+
+ @Override
+ public void onPause() {
+ mSettingObserver.register(mContext.getContentResolver(), false);
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.ASSIST_SCREENSHOT_ENABLED,
+ (boolean) newValue ? 1 : 0);
+ return true;
+ }
+
+ private void updatePreference() {
+ if (mPreference == null || !(mPreference instanceof TwoStatePreference)) {
+ return;
+ }
+ if (isAvailable()) {
+ if (mScreen.findPreference(getPreferenceKey()) == null) {
+ // add it if it's not on scree
+ mScreen.addPreference(mPreference);
+ }
+ } else {
+ mScreen.removePreference(mPreference);
+ }
+ final boolean checked = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.ASSIST_SCREENSHOT_ENABLED, 1) != 0;
+ ((TwoStatePreference) mPreference).setChecked(checked);
+ final boolean contextChecked = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.ASSIST_STRUCTURE_ENABLED, 1) != 0;
+ mPreference.setEnabled(contextChecked);
+ }
+
+ class SettingObserver extends AssistSettingObserver {
+
+ private final Uri URI =
+ Settings.Secure.getUriFor(Settings.Secure.ASSIST_SCREENSHOT_ENABLED);
+ private final Uri CONTEXT_URI =
+ Settings.Secure.getUriFor(Settings.Secure.ASSIST_STRUCTURE_ENABLED);
+
+ @Override
+ protected List<Uri> getSettingUris() {
+ return Arrays.asList(URI, CONTEXT_URI);
+ }
+
+ @Override
+ public void onSettingChange() {
+ updatePreference();
+ }
+ }
+}
diff --git a/src/com/android/settings/applications/assist/AssistSettingObserver.java b/src/com/android/settings/applications/assist/AssistSettingObserver.java
new file mode 100644
index 0000000..5d3d4a7
--- /dev/null
+++ b/src/com/android/settings/applications/assist/AssistSettingObserver.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2017 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.assist;
+
+import android.content.ContentResolver;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.provider.Settings;
+
+import java.util.List;
+
+public abstract class AssistSettingObserver extends ContentObserver {
+
+ private final Uri ASSIST_URI =
+ Settings.Secure.getUriFor(Settings.Secure.ASSISTANT);
+
+ public AssistSettingObserver() {
+ super(new Handler());
+ }
+
+ public void register(ContentResolver cr, boolean register) {
+ if (register) {
+ cr.registerContentObserver(ASSIST_URI, false, this);
+ final List<Uri> settingUri = getSettingUris();
+ if (settingUri != null) {
+ for (Uri uri : settingUri)
+ cr.registerContentObserver(uri, false, this);
+ }
+ } else {
+ cr.unregisterContentObserver(this);
+ }
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ super.onChange(selfChange, uri);
+ boolean shouldUpdatePreference = false;
+ final List<Uri> settingUri = getSettingUris();
+ if (ASSIST_URI.equals(uri) || (settingUri != null && settingUri.contains(uri))) {
+ shouldUpdatePreference = true;
+ }
+ if (shouldUpdatePreference) {
+ onSettingChange();
+ }
+ }
+
+ protected abstract List<Uri> getSettingUris();
+
+ public abstract void onSettingChange();
+}
diff --git a/src/com/android/settings/applications/DefaultAssistPreference.java b/src/com/android/settings/applications/assist/DefaultAssistPicker.java
similarity index 62%
rename from src/com/android/settings/applications/DefaultAssistPreference.java
rename to src/com/android/settings/applications/assist/DefaultAssistPicker.java
index 0bd729e..703665a 100644
--- a/src/com/android/settings/applications/DefaultAssistPreference.java
+++ b/src/com/android/settings/applications/assist/DefaultAssistPicker.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2017 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.
@@ -11,49 +11,105 @@
* 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
+ * limitations under the License.
*/
-package com.android.settings.applications;
+package com.android.settings.applications.assist;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
-import android.os.UserHandle;
import android.provider.Settings;
import android.service.voice.VoiceInteractionService;
import android.service.voice.VoiceInteractionServiceInfo;
import android.speech.RecognitionService;
-import android.util.AttributeSet;
+import android.text.TextUtils;
import android.util.Log;
import com.android.internal.app.AssistUtils;
-import com.android.settings.AppListPreferenceWithSettings;
+import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
+import com.android.settings.applications.defaultapps.DefaultAppInfo;
+import com.android.settings.applications.defaultapps.DefaultAppPickerFragment;
import java.util.ArrayList;
import java.util.List;
-public class DefaultAssistPreference extends AppListPreferenceWithSettings {
+public class DefaultAssistPicker extends DefaultAppPickerFragment {
- private static final String TAG = DefaultAssistPreference.class.getSimpleName();
-
+ private static final String TAG = "DefaultAssistPicker";
+ private static final Intent ASSIST_SERVICE_PROBE =
+ new Intent(VoiceInteractionService.SERVICE_INTERFACE);
+ private static final Intent ASSIST_ACTIVITY_PROBE =
+ new Intent(Intent.ACTION_ASSIST);
private final List<Info> mAvailableAssistants = new ArrayList<>();
- private final AssistUtils mAssistUtils;
+ private AssistUtils mAssistUtils;
- public DefaultAssistPreference(Context context, AttributeSet attrs) {
- super(context, attrs);
- setShowItemNone(true);
- setDialogTitle(R.string.choose_assist_title);
+ @Override
+ public int getMetricsCategory() {
+ return MetricsProto.MetricsEvent.DEFAULT_ASSIST_PICKER;
+ }
+
+ @Override
+ protected boolean shouldShowItemNone() {
+ return true;
+ }
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
mAssistUtils = new AssistUtils(context);
}
@Override
- protected boolean persistString(String value) {
- final Info info = findAssistantByPackageName(value);
+ protected List<DefaultAppInfo> getCandidates() {
+ mAvailableAssistants.clear();
+ addAssistServices();
+ addAssistActivities();
+
+ final List<String> packages = new ArrayList<>();
+ final List<DefaultAppInfo> candidates = new ArrayList<>();
+ for (Info info : mAvailableAssistants) {
+ final String packageName = info.component.getPackageName();
+ if (packages.contains(packageName)) {
+ // A service appears before an activity thus overrides it if from the same package.
+ continue;
+ }
+ packages.add(packageName);
+ candidates.add(new DefaultAppInfo(mUserId, info.component));
+ }
+ return candidates;
+ }
+
+ @Override
+ protected String getDefaultAppKey() {
+ final ComponentName cn = getCurrentAssist();
+ if (cn != null) {
+ return new DefaultAppInfo(mUserId, cn).getKey();
+ }
+ return null;
+ }
+
+ @Override
+ protected String getConfirmationMessage(DefaultAppInfo appInfo) {
+ if (appInfo == null) {
+ return null;
+ }
+ return getContext().getString(R.string.assistant_security_warning,
+ appInfo.loadLabel(mPm.getPackageManager()));
+ }
+
+ @Override
+ protected boolean setDefaultAppKey(String key) {
+ if (TextUtils.isEmpty(key)) {
+ setAssistNone();
+ return true;
+ }
+ ComponentName cn = ComponentName.unflattenFromString(key);
+ final Info info = findAssistantByPackageName(cn.getPackageName());
if (info == null) {
setAssistNone();
return true;
@@ -67,20 +123,60 @@
return true;
}
+ public ComponentName getCurrentAssist() {
+ return mAssistUtils.getAssistComponentForUser(mUserId);
+ }
+
+ private void addAssistServices() {
+ final PackageManager pm = mPm.getPackageManager();
+ final List<ResolveInfo> services = pm.queryIntentServices(
+ ASSIST_SERVICE_PROBE, PackageManager.GET_META_DATA);
+ for (ResolveInfo resolveInfo : services) {
+ 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() {
+ final PackageManager pm = mPm.getPackageManager();
+ final List<ResolveInfo> activities = pm.queryIntentActivities(
+ ASSIST_ACTIVITY_PROBE, PackageManager.MATCH_DEFAULT_ONLY);
+ for (ResolveInfo resolveInfo : activities) {
+ mAvailableAssistants.add(new Info(
+ new ComponentName(resolveInfo.activityInfo.packageName,
+ resolveInfo.activityInfo.name)));
+ }
+ }
+
+ private Info findAssistantByPackageName(String packageName) {
+ for (Info info : mAvailableAssistants) {
+ if (TextUtils.equals(info.component.getPackageName(), packageName)) {
+ return info;
+ }
+ }
+ return null;
+ }
+
private void setAssistNone() {
Settings.Secure.putString(getContext().getContentResolver(),
- Settings.Secure.ASSISTANT, ITEM_NONE_VALUE);
+ Settings.Secure.ASSISTANT, "");
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 serviceComponentName = serviceInfo.component.
+ flattenToShortString();
final String serviceRecognizerName = new ComponentName(
serviceInfo.component.getPackageName(),
serviceInfo.voiceInteractionServiceInfo.getRecognitionService())
@@ -92,13 +188,6 @@
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) {
@@ -108,13 +197,10 @@
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(
+ final ResolveInfo resolveInfo = mPm.getPackageManager().resolveService(
new Intent(RecognitionService.SERVICE_INTERFACE),
PackageManager.GET_META_DATA);
if (resolveInfo == null || resolveInfo.serviceInfo == null) {
@@ -126,76 +212,7 @@
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() {
- return mAssistUtils.getAssistComponentForUser(UserHandle.myUserId());
- }
-
- 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 {
+ static class Info {
public final ComponentName component;
public final VoiceInteractionServiceInfo voiceInteractionServiceInfo;
diff --git a/src/com/android/settings/applications/assist/DefaultAssistPreferenceController.java b/src/com/android/settings/applications/assist/DefaultAssistPreferenceController.java
new file mode 100644
index 0000000..df34501
--- /dev/null
+++ b/src/com/android/settings/applications/assist/DefaultAssistPreferenceController.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2017 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.assist;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.service.voice.VoiceInteractionService;
+import android.service.voice.VoiceInteractionServiceInfo;
+
+import com.android.internal.app.AssistUtils;
+import com.android.settings.applications.defaultapps.DefaultAppInfo;
+import com.android.settings.applications.defaultapps.DefaultAppPreferenceController;
+
+import java.util.List;
+
+public class DefaultAssistPreferenceController extends DefaultAppPreferenceController {
+
+ private static final String KEY_DEFAULT_ASSIST = "default_assist";
+
+ private AssistUtils mAssistUtils;
+
+ public DefaultAssistPreferenceController(Context context) {
+ super(context);
+ mAssistUtils = new AssistUtils(context);
+ }
+
+ @Override
+ protected Intent getSettingIntent(DefaultAppInfo info) {
+ final ComponentName cn = mAssistUtils.getAssistComponentForUser(mUserId);
+ if (cn == null) {
+ return null;
+ }
+ final Intent probe = new Intent(VoiceInteractionService.SERVICE_INTERFACE)
+ .setPackage(cn.getPackageName());
+
+ final PackageManager pm = mPackageManager.getPackageManager();
+ final List<ResolveInfo> services = pm.queryIntentServices(probe, PackageManager
+ .GET_META_DATA);
+ if (services == null || services.isEmpty()) {
+ return null;
+ }
+ final ResolveInfo resolveInfo = services.get(0);
+ final VoiceInteractionServiceInfo voiceInfo =
+ new VoiceInteractionServiceInfo(pm, resolveInfo.serviceInfo);
+ if (!voiceInfo.getSupportsAssist()) {
+ return null;
+ }
+ final String activity = voiceInfo.getSettingsActivity();
+ return new Intent(Intent.ACTION_MAIN)
+ .setComponent(new ComponentName(cn.getPackageName(), activity));
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_DEFAULT_ASSIST;
+ }
+
+ @Override
+ protected DefaultAppInfo getDefaultAppInfo() {
+ final ComponentName cn = mAssistUtils.getAssistComponentForUser(mUserId);
+ if (cn == null) {
+ return null;
+ }
+ return new DefaultAppInfo(mUserId, cn);
+ }
+}
diff --git a/src/com/android/settings/applications/assist/DefaultVoiceInputPicker.java b/src/com/android/settings/applications/assist/DefaultVoiceInputPicker.java
new file mode 100644
index 0000000..7168aa5
--- /dev/null
+++ b/src/com/android/settings/applications/assist/DefaultVoiceInputPicker.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2017 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.assist;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.provider.Settings;
+import android.text.TextUtils;
+
+import com.android.internal.app.AssistUtils;
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.applications.defaultapps.DefaultAppInfo;
+import com.android.settings.applications.defaultapps.DefaultAppPickerFragment;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class DefaultVoiceInputPicker extends DefaultAppPickerFragment {
+
+ private VoiceInputHelper mHelper;
+ private AssistUtils mAssistUtils;
+ private String mAssistRestrict;
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsProto.MetricsEvent.DEFAULT_VOICE_INPUT_PICKER;
+ }
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ mAssistUtils = new AssistUtils(context);
+ mHelper = new VoiceInputHelper(context);
+ mHelper.buildUi();
+ final ComponentName assist = getCurrentAssist();
+ if (isCurrentAssistVoiceService(assist, getCurrentService(mHelper))) {
+ mAssistRestrict = assist.flattenToShortString();
+ }
+ }
+
+ @Override
+ protected List<VoiceInputDefaultAppInfo> getCandidates() {
+ final List<VoiceInputDefaultAppInfo> candidates = new ArrayList<>();
+ boolean hasEnabled = true;
+ for (VoiceInputHelper.InteractionInfo info : mHelper.mAvailableInteractionInfos) {
+ final boolean enabled = TextUtils.equals(info.key, mAssistRestrict);
+ hasEnabled |= enabled;
+ candidates.add(new VoiceInputDefaultAppInfo(mUserId, info, enabled));
+ }
+
+ final boolean assistIsService = !hasEnabled;
+ for (VoiceInputHelper.RecognizerInfo info : mHelper.mAvailableRecognizerInfos) {
+ final boolean enabled = !assistIsService;
+ candidates.add(new VoiceInputDefaultAppInfo(mUserId, info, enabled));
+ }
+ return candidates;
+ }
+
+ @Override
+ protected String getDefaultAppKey() {
+ final ComponentName currentService = getCurrentService(mHelper);
+ if (currentService == null) {
+ return null;
+ }
+ return currentService.flattenToShortString();
+ }
+
+ @Override
+ protected boolean setDefaultAppKey(String value) {
+ for (VoiceInputHelper.InteractionInfo info : mHelper.mAvailableInteractionInfos) {
+ if (TextUtils.equals(value, info.key)) {
+ 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());
+ return true;
+ }
+ }
+
+ for (VoiceInputHelper.RecognizerInfo info : mHelper.mAvailableRecognizerInfos) {
+ if (TextUtils.equals(value, info.key)) {
+ Settings.Secure.putString(getContext().getContentResolver(),
+ Settings.Secure.VOICE_INTERACTION_SERVICE, "");
+ Settings.Secure.putString(getContext().getContentResolver(),
+ Settings.Secure.VOICE_RECOGNITION_SERVICE, value);
+ return true;
+ }
+ }
+ return true;
+ }
+
+ public static ComponentName getCurrentService(VoiceInputHelper helper) {
+ if (helper.mCurrentVoiceInteraction != null) {
+ return helper.mCurrentVoiceInteraction;
+ } else if (helper.mCurrentRecognizer != null) {
+ return helper.mCurrentRecognizer;
+ } else {
+ return null;
+ }
+ }
+
+ private ComponentName getCurrentAssist() {
+ return mAssistUtils.getAssistComponentForUser(mUserId);
+ }
+
+ public static boolean isCurrentAssistVoiceService(ComponentName currentAssist,
+ ComponentName currentVoiceService) {
+ return currentAssist == null && currentVoiceService == null ||
+ currentAssist != null && currentAssist.equals(currentVoiceService);
+ }
+
+ public static class VoiceInputDefaultAppInfo extends DefaultAppInfo {
+
+ public VoiceInputHelper.BaseInfo mInfo;
+
+ public VoiceInputDefaultAppInfo(int userId, VoiceInputHelper.BaseInfo info,
+ boolean enabled) {
+ super(userId, info.componentName, null /* summary */, enabled);
+ mInfo = info;
+ }
+
+ @Override
+ public String getKey() {
+ return mInfo.key;
+ }
+
+ @Override
+ public CharSequence loadLabel(PackageManager pm) {
+ if (mInfo instanceof VoiceInputHelper.InteractionInfo) {
+ return mInfo.appLabel;
+ } else {
+ return mInfo.label;
+ }
+ }
+
+ public Intent getSettingIntent() {
+ if (mInfo.settings == null) {
+ return null;
+ }
+ return new Intent(Intent.ACTION_MAIN).setComponent(mInfo.settings);
+ }
+ }
+}
diff --git a/src/com/android/settings/applications/assist/DefaultVoiceInputPreferenceController.java b/src/com/android/settings/applications/assist/DefaultVoiceInputPreferenceController.java
new file mode 100644
index 0000000..918ec9c
--- /dev/null
+++ b/src/com/android/settings/applications/assist/DefaultVoiceInputPreferenceController.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2017 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.assist;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.text.TextUtils;
+
+import com.android.internal.app.AssistUtils;
+import com.android.settings.applications.defaultapps.DefaultAppInfo;
+import com.android.settings.applications.defaultapps.DefaultAppPreferenceController;
+import com.android.settings.core.lifecycle.Lifecycle;
+import com.android.settings.core.lifecycle.LifecycleObserver;
+import com.android.settings.core.lifecycle.events.OnPause;
+import com.android.settings.core.lifecycle.events.OnResume;
+
+import java.util.List;
+
+public class DefaultVoiceInputPreferenceController extends DefaultAppPreferenceController
+ implements LifecycleObserver, OnResume, OnPause {
+
+ private static final String KEY_VOICE_INPUT = "voice_input_settings";
+
+ private VoiceInputHelper mHelper;
+ private AssistUtils mAssistUtils;
+ private PreferenceScreen mScreen;
+ private Preference mPreference;
+ private SettingObserver mSettingObserver;
+
+ public DefaultVoiceInputPreferenceController(Context context, Lifecycle lifecycle) {
+ super(context);
+ mSettingObserver = new SettingObserver();
+ mAssistUtils = new AssistUtils(context);
+ mHelper = new VoiceInputHelper(context);
+ mHelper.buildUi();
+ if (lifecycle != null) {
+ lifecycle.addObserver(this);
+ }
+ }
+
+ @Override
+ public boolean isAvailable() {
+ // If current assist is also voice service, don't show voice preference.
+ final ComponentName currentVoiceService =
+ DefaultVoiceInputPicker.getCurrentService(mHelper);
+ final ComponentName currentAssist =
+ mAssistUtils.getAssistComponentForUser(mUserId);
+ return !DefaultVoiceInputPicker.isCurrentAssistVoiceService(
+ currentAssist, currentVoiceService);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_VOICE_INPUT;
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ mScreen = screen;
+ mPreference = screen.findPreference(getPreferenceKey());
+ super.displayPreference(screen);
+ }
+
+ @Override
+ public void onResume() {
+ mSettingObserver.register(mContext.getContentResolver(), true);
+ updatePreference();
+ }
+
+ @Override
+ public void updateState(Preference preference) {
+ super.updateState(mPreference);
+ updatePreference();
+ }
+
+ @Override
+ public void onPause() {
+ mSettingObserver.register(mContext.getContentResolver(), false);
+ }
+
+ @Override
+ protected DefaultAppInfo getDefaultAppInfo() {
+ final String defaultKey = getDefaultAppKey();
+ if (defaultKey == null) {
+ return null;
+ }
+ for (VoiceInputHelper.InteractionInfo info : mHelper.mAvailableInteractionInfos) {
+ if (TextUtils.equals(defaultKey, info.key)) {
+ return new DefaultVoiceInputPicker.VoiceInputDefaultAppInfo(
+ mUserId, info, true /* enabled */);
+ }
+ }
+
+ for (VoiceInputHelper.RecognizerInfo info : mHelper.mAvailableRecognizerInfos) {
+ if (TextUtils.equals(defaultKey, info.key)) {
+ return new DefaultVoiceInputPicker.VoiceInputDefaultAppInfo(
+ mUserId, info, true /* enabled */);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ protected Intent getSettingIntent(DefaultAppInfo info) {
+ final DefaultAppInfo appInfo = getDefaultAppInfo();
+ if (appInfo == null
+ || !(appInfo instanceof DefaultVoiceInputPicker.VoiceInputDefaultAppInfo)) {
+ return null;
+ }
+ return ((DefaultVoiceInputPicker.VoiceInputDefaultAppInfo) appInfo).getSettingIntent();
+ }
+
+ private void updatePreference() {
+ if (mPreference == null) {
+ return;
+ }
+ mHelper.buildUi();
+ if (isAvailable()) {
+ if (mScreen.findPreference(getPreferenceKey()) == null) {
+ // add it if it's not on scree
+ mScreen.addPreference(mPreference);
+ }
+ } else {
+ mScreen.removePreference(mPreference);
+ }
+ }
+
+ private String getDefaultAppKey() {
+ final ComponentName currentService = DefaultVoiceInputPicker.getCurrentService(mHelper);
+ if (currentService == null) {
+ return null;
+ }
+ return currentService.flattenToShortString();
+ }
+
+ class SettingObserver extends AssistSettingObserver {
+ @Override
+ protected List<Uri> getSettingUris() {
+ return null;
+ }
+
+ @Override
+ public void onSettingChange() {
+ updatePreference();
+ }
+ }
+}
diff --git a/src/com/android/settings/applications/assist/GestureAssistPreferenceController.java b/src/com/android/settings/applications/assist/GestureAssistPreferenceController.java
new file mode 100644
index 0000000..bd85a03
--- /dev/null
+++ b/src/com/android/settings/applications/assist/GestureAssistPreferenceController.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2017 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.assist;
+
+import android.content.Context;
+
+import com.android.settings.core.PreferenceController;
+import com.android.settings.gestures.AssistGestureFeatureProvider;
+import com.android.settings.overlay.FeatureFactory;
+
+public class GestureAssistPreferenceController extends PreferenceController {
+
+ private static final String KEY_ASSIST_GESTURE = "gesture_assist";
+
+ private AssistGestureFeatureProvider mFeatureProvider;
+
+ public GestureAssistPreferenceController(Context context) {
+ super(context);
+ mFeatureProvider = FeatureFactory.getFactory(context)
+ .getAssistGestureFeatureProvider();
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return mFeatureProvider.isSupported(mContext);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_ASSIST_GESTURE;
+ }
+}
diff --git a/src/com/android/settings/applications/assist/ManageAssist.java b/src/com/android/settings/applications/assist/ManageAssist.java
new file mode 100644
index 0000000..b1ca5c6
--- /dev/null
+++ b/src/com/android/settings/applications/assist/ManageAssist.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2017 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.assist;
+
+import android.content.Context;
+import android.provider.SearchIndexableResource;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.R;
+import com.android.settings.core.PreferenceController;
+import com.android.settings.core.lifecycle.Lifecycle;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.search.Indexable;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Settings screen to manage everything about assist.
+ */
+public class ManageAssist extends DashboardFragment {
+
+ private static final String TAG = "ManageAssist";
+
+ @Override
+ protected String getLogTag() {
+ return TAG;
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.manage_assist;
+ }
+
+ @Override
+ protected List<PreferenceController> getPreferenceControllers(Context context) {
+ final Lifecycle lifecycle = getLifecycle();
+ final List<PreferenceController> controllers = new ArrayList<>();
+ controllers.add(new DefaultAssistPreferenceController(context));
+ controllers.add(new GestureAssistPreferenceController(context));
+ controllers.add(new AssistContextPreferenceController(context, lifecycle));
+ controllers.add(new AssistScreenshotPreferenceController(context, lifecycle));
+ controllers.add(new AssistFlashScreenPreferenceController(context, lifecycle));
+ controllers.add(new DefaultVoiceInputPreferenceController(context, lifecycle));
+ return controllers;
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsEvent.APPLICATIONS_MANAGE_ASSIST;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ mFooterPreferenceMixin.createFooterPreference()
+ .setTitle(R.string.assist_footer);
+ }
+
+ public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+ new BaseSearchIndexProvider() {
+ @Override
+ public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
+ boolean enabled) {
+ final SearchIndexableResource sir = new SearchIndexableResource(context);
+ sir.xmlResId = R.xml.manage_assist;
+ return Arrays.asList(sir);
+ }
+
+ @Override
+ public List<String> getNonIndexableKeys(Context context) {
+ List<String> result = new ArrayList<>();
+ new DefaultAssistPreferenceController(context).updateNonIndexableKeys(result);
+ new GestureAssistPreferenceController(context).updateNonIndexableKeys(result);
+ new AssistContextPreferenceController(context, null)
+ .updateNonIndexableKeys(result);
+ new AssistScreenshotPreferenceController(context, null)
+ .updateNonIndexableKeys(result);
+ new AssistFlashScreenPreferenceController(context, null)
+ .updateNonIndexableKeys(result);
+ new DefaultVoiceInputPreferenceController(context, null)
+ .updateNonIndexableKeys(result);
+ return result;
+ }
+ };
+}
diff --git a/src/com/android/settings/voice/VoiceInputHelper.java b/src/com/android/settings/applications/assist/VoiceInputHelper.java
similarity index 92%
rename from src/com/android/settings/voice/VoiceInputHelper.java
rename to src/com/android/settings/applications/assist/VoiceInputHelper.java
index ac73d84..58c0d49 100644
--- a/src/com/android/settings/voice/VoiceInputHelper.java
+++ b/src/com/android/settings/applications/assist/VoiceInputHelper.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2017 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.settings.voice;
+package com.android.settings.applications.assist;
import android.content.ComponentName;
import android.content.Context;
@@ -71,7 +71,7 @@
@Override
public int compareTo(Object another) {
- return labelStr.compareTo(((BaseInfo)another).labelStr);
+ return labelStr.compareTo(((BaseInfo) another).labelStr);
}
}
@@ -100,15 +100,11 @@
mContext = context;
mAvailableVoiceInteractions = mContext.getPackageManager().queryIntentServices(
- new Intent(VoiceInteractionService.SERVICE_INTERFACE),
- PackageManager.GET_META_DATA);
+ new Intent(VoiceInteractionService.SERVICE_INTERFACE),
+ PackageManager.GET_META_DATA);
mAvailableRecognition = mContext.getPackageManager().queryIntentServices(
- new Intent(RecognitionService.SERVICE_INTERFACE),
- PackageManager.GET_META_DATA);
- }
-
- public boolean hasItems() {
- return mAvailableVoiceInteractions.size() > 0 || mAvailableRecognition.size() > 0;
+ new Intent(RecognitionService.SERVICE_INTERFACE),
+ PackageManager.GET_META_DATA);
}
public void buildUi() {
@@ -178,7 +174,7 @@
AttributeSet attrs = Xml.asAttributeSet(parser);
int type;
- while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
&& type != XmlPullParser.START_TAG) {
}
diff --git a/src/com/android/settings/applications/defaultapps/DefaultAppInfo.java b/src/com/android/settings/applications/defaultapps/DefaultAppInfo.java
index ea3a27a..96512f5 100644
--- a/src/com/android/settings/applications/defaultapps/DefaultAppInfo.java
+++ b/src/com/android/settings/applications/defaultapps/DefaultAppInfo.java
@@ -37,13 +37,23 @@
public final String summary;
// Description for why this item is disabled, if null, the item is enabled.
public final String disabledDescription;
+ public final boolean enabled;
+
+ public DefaultAppInfo(int uid, ComponentName cn) {
+ this(uid, cn, null /* summary */);
+ }
public DefaultAppInfo(int uid, ComponentName cn, String summary) {
+ this(uid, cn, summary, true /* enabled */);
+ }
+
+ public DefaultAppInfo(int uid, ComponentName cn, String summary, boolean enabled) {
packageItemInfo = null;
userId = uid;
componentName = cn;
this.summary = summary;
this.disabledDescription = null;
+ this.enabled = enabled;
}
public DefaultAppInfo(PackageItemInfo info, String description) {
@@ -52,6 +62,7 @@
componentName = null;
summary = null;
this.disabledDescription = description;
+ enabled = true;
}
public DefaultAppInfo(PackageItemInfo info) {
diff --git a/src/com/android/settings/applications/defaultapps/DefaultAppPickerFragment.java b/src/com/android/settings/applications/defaultapps/DefaultAppPickerFragment.java
index 358b5f4..e4bcf06 100644
--- a/src/com/android/settings/applications/defaultapps/DefaultAppPickerFragment.java
+++ b/src/com/android/settings/applications/defaultapps/DefaultAppPickerFragment.java
@@ -97,7 +97,7 @@
@VisibleForTesting
public void updateCandidates() {
mCandidates.clear();
- final List<DefaultAppInfo> candidateList = getCandidates();
+ final List<? extends DefaultAppInfo> candidateList = getCandidates();
if (candidateList != null) {
for (DefaultAppInfo info : candidateList) {
mCandidates.put(info.getKey(), info);
@@ -134,6 +134,7 @@
pref.setEnabled(false);
pref.setSummary(app.getValue().disabledDescription);
}
+ pref.setEnabled(info.enabled);
pref.setOnClickListener(this);
screen.addPreference(pref);
}
@@ -200,14 +201,15 @@
return null;
}
- protected abstract List<DefaultAppInfo> getCandidates();
+ protected abstract List<? extends DefaultAppInfo> getCandidates();
protected abstract String getDefaultAppKey();
protected abstract boolean setDefaultAppKey(String key);
// Called after the user tries to select an item.
- protected void onSelectionPerformed(boolean success) {}
+ protected void onSelectionPerformed(boolean success) {
+ }
protected String getConfirmationMessage(DefaultAppInfo appInfo) {
return null;
diff --git a/src/com/android/settings/applications/defaultapps/DefaultAutoFillPicker.java b/src/com/android/settings/applications/defaultapps/DefaultAutoFillPicker.java
index 5b9fed4..b8190cd 100644
--- a/src/com/android/settings/applications/defaultapps/DefaultAutoFillPicker.java
+++ b/src/com/android/settings/applications/defaultapps/DefaultAutoFillPicker.java
@@ -54,7 +54,7 @@
.queryIntentServices(AUTO_FILL_PROBE, PackageManager.GET_META_DATA);
for (ResolveInfo info : resolveInfos) {
candidates.add(new DefaultAppInfo(mUserId, new ComponentName(
- info.serviceInfo.packageName, info.serviceInfo.name), null /* summary */));
+ info.serviceInfo.packageName, info.serviceInfo.name)));
}
return candidates;
}
diff --git a/src/com/android/settings/applications/defaultapps/DefaultAutoFillPreferenceController.java b/src/com/android/settings/applications/defaultapps/DefaultAutoFillPreferenceController.java
index 35e4ade..b7f3b77 100644
--- a/src/com/android/settings/applications/defaultapps/DefaultAutoFillPreferenceController.java
+++ b/src/com/android/settings/applications/defaultapps/DefaultAutoFillPreferenceController.java
@@ -55,7 +55,7 @@
DefaultAutoFillPicker.SETTING);
if (!TextUtils.isEmpty(flattenComponent)) {
DefaultAppInfo appInfo = new DefaultAppInfo(
- mUserId, ComponentName.unflattenFromString(flattenComponent), null /*summary*/);
+ mUserId, ComponentName.unflattenFromString(flattenComponent));
return appInfo;
}
return null;
diff --git a/src/com/android/settings/applications/defaultapps/DefaultHomePreferenceController.java b/src/com/android/settings/applications/defaultapps/DefaultHomePreferenceController.java
index 055c23b..7366d18 100644
--- a/src/com/android/settings/applications/defaultapps/DefaultHomePreferenceController.java
+++ b/src/com/android/settings/applications/defaultapps/DefaultHomePreferenceController.java
@@ -75,7 +75,7 @@
final ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
final ComponentName currentDefaultHome = mPackageManager.getHomeActivities(homeActivities);
- return new DefaultAppInfo(mUserId, currentDefaultHome, null /* summary */);
+ return new DefaultAppInfo(mUserId, currentDefaultHome);
}
private String getOnlyAppLabel() {
diff --git a/src/com/android/settings/applications/defaultapps/DefaultNotificationAssistantPicker.java b/src/com/android/settings/applications/defaultapps/DefaultNotificationAssistantPicker.java
index af67917..06c5401 100644
--- a/src/com/android/settings/applications/defaultapps/DefaultNotificationAssistantPicker.java
+++ b/src/com/android/settings/applications/defaultapps/DefaultNotificationAssistantPicker.java
@@ -76,7 +76,7 @@
}
candidates.add(new DefaultAppInfo(
- mUserId, new ComponentName(info.packageName, info.name), null /* summary */));
+ mUserId, new ComponentName(info.packageName, info.name)));
}
return candidates;
}
diff --git a/src/com/android/settings/applications/defaultapps/DefaultSmsPreferenceController.java b/src/com/android/settings/applications/defaultapps/DefaultSmsPreferenceController.java
index 90b9d83..81a3af0 100644
--- a/src/com/android/settings/applications/defaultapps/DefaultSmsPreferenceController.java
+++ b/src/com/android/settings/applications/defaultapps/DefaultSmsPreferenceController.java
@@ -47,7 +47,7 @@
protected DefaultAppInfo getDefaultAppInfo() {
final ComponentName app = SmsApplication.getDefaultSmsApplication(mContext, true);
if (app != null) {
- return new DefaultAppInfo(mUserId, app, null /* summary */);
+ return new DefaultAppInfo(mUserId, app);
}
return null;
}
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index 92d6ace..ad8bdaf 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -54,7 +54,7 @@
import com.android.settings.applications.DrawOverlayDetails;
import com.android.settings.applications.InstalledAppDetails;
import com.android.settings.applications.ManageApplications;
-import com.android.settings.applications.ManageAssist;
+import com.android.settings.applications.assist.ManageAssist;
import com.android.settings.applications.ManageDomainUrls;
import com.android.settings.applications.NotificationApps;
import com.android.settings.applications.PictureInPictureSettings;
diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java
index 700ab72..6688b99 100644
--- a/src/com/android/settings/search/SearchIndexableResources.java
+++ b/src/com/android/settings/search/SearchIndexableResources.java
@@ -37,6 +37,7 @@
import com.android.settings.applications.AdvancedAppSettings;
import com.android.settings.applications.AppAndNotificationDashboardFragment;
import com.android.settings.applications.SpecialAccessSettings;
+import com.android.settings.applications.assist.ManageAssist;
import com.android.settings.backup.BackupSettingsFragment;
import com.android.settings.bluetooth.BluetoothSettings;
import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment;
@@ -133,6 +134,7 @@
addIndex(BatterySaverSettings.class,
R.xml.battery_saver_settings, R.drawable.ic_settings_battery);
addIndex(AdvancedAppSettings.class, NO_DATA_RES_ID, R.drawable.ic_settings_applications);
+ addIndex(ManageAssist.class, NO_DATA_RES_ID, R.drawable.ic_settings_applications);
addIndex(SpecialAccessSettings.class,
R.xml.special_access, R.drawable.ic_settings_applications);
addIndex(UserSettings.class, NO_DATA_RES_ID, R.drawable.ic_settings_multiuser);
diff --git a/src/com/android/settings/voice/VoiceInputListPreference.java b/src/com/android/settings/voice/VoiceInputListPreference.java
deleted file mode 100644
index ddb56d1..0000000
--- a/src/com/android/settings/voice/VoiceInputListPreference.java
+++ /dev/null
@@ -1,158 +0,0 @@
-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);
- }
- }
-
- public ComponentName getCurrentService() {
- if (mHelper.mCurrentVoiceInteraction != null) {
- return mHelper.mCurrentVoiceInteraction;
- } else if (mHelper.mCurrentRecognizer != null) {
- return mHelper.mCurrentRecognizer;
- } else {
- return 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;
- }
- }
-}