Loading src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java +28 −7 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.settings.accessibility; import android.accessibilityservice.AccessibilityServiceInfo; import android.annotation.Nullable; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; Loading @@ -27,6 +28,7 @@ import android.support.v7.preference.Preference; import android.view.accessibility.AccessibilityManager; import android.widget.Switch; import com.android.internal.accessibility.AccessibilityShortcutController; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; import com.android.settings.search.BaseSearchIndexProvider; Loading Loading @@ -87,7 +89,7 @@ public class AccessibilityShortcutPreferenceFragment extends ToggleFeaturePrefer super.onInstallSwitchBarToggleSwitch(); mSwitchBar.addOnSwitchChangeListener((Switch switchView, boolean enabled) -> { Context context = getContext(); if (enabled && (getServiceInfo(context) == null)) { if (enabled && !shortcutFeatureAvailable(context)) { // If no service is configured, we'll disable the shortcut shortly. Give the // user a chance to select a service. We'll update the preferences when we resume. Settings.Secure.putInt( Loading @@ -110,7 +112,7 @@ public class AccessibilityShortcutPreferenceFragment extends ToggleFeaturePrefer ContentResolver cr = getContentResolver(); Context context = getContext(); mServicePreference.setSummary(getServiceName(context)); if (getServiceInfo(context) == null) { if (!shortcutFeatureAvailable(context)) { // If no service is configured, make sure the overall shortcut is turned off Settings.Secure.putInt( getContentResolver(), Settings.Secure.ACCESSIBILITY_SHORTCUT_ENABLED, 0); Loading @@ -132,19 +134,38 @@ public class AccessibilityShortcutPreferenceFragment extends ToggleFeaturePrefer * @return The name of the service or a string saying that none is selected. */ public static CharSequence getServiceName(Context context) { if (!shortcutFeatureAvailable(context)) { return context.getString(R.string.accessibility_no_service_selected); } AccessibilityServiceInfo shortcutServiceInfo = getServiceInfo(context); if (shortcutServiceInfo != null) { return shortcutServiceInfo.getResolveInfo().loadLabel(context.getPackageManager()); } return context.getString(R.string.accessibility_no_service_selected); return AccessibilityShortcutController.getFrameworkShortcutFeaturesMap() .get(getShortcutComponent(context)).getLabel(context); } private static AccessibilityServiceInfo getServiceInfo(Context context) { ComponentName shortcutServiceName = ComponentName.unflattenFromString( AccessibilityUtils.getShortcutTargetServiceComponentNameString( context, UserHandle.myUserId())); return AccessibilityManager.getInstance(context) .getInstalledServiceInfoWithComponentName(shortcutServiceName); .getInstalledServiceInfoWithComponentName(getShortcutComponent(context)); } private static boolean shortcutFeatureAvailable(Context context) { ComponentName shortcutFeature = getShortcutComponent(context); if (shortcutFeature == null) return false; if (AccessibilityShortcutController.getFrameworkShortcutFeaturesMap() .containsKey(shortcutFeature)) { return true; } return getServiceInfo(context) != null; } private static @Nullable ComponentName getShortcutComponent(Context context) { String componentNameString = AccessibilityUtils.getShortcutTargetServiceComponentNameString( context, UserHandle.myUserId()); if (componentNameString == null) return null; return ComponentName.unflattenFromString(componentNameString); } public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = Loading src/com/android/settings/accessibility/ShortcutServicePickerFragment.java +70 −15 Original line number Diff line number Diff line Loading @@ -25,29 +25,40 @@ import android.app.Fragment; import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; import android.content.pm.ApplicationInfo; import android.content.pm.ComponentInfo; import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; import android.os.UserHandle; import android.provider.Settings; import android.text.TextUtils; import android.util.IconDrawableFactory; import android.view.accessibility.AccessibilityManager; import com.android.internal.accessibility.AccessibilityShortcutController; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.accessibility.AccessibilityShortcutController.ToggleableFrameworkFeatureInfo; import com.android.settings.R; import com.android.settings.applications.defaultapps.DefaultAppInfo; import com.android.settings.applications.defaultapps.DefaultAppPickerFragment; import com.android.settings.core.instrumentation.InstrumentedDialogFragment; import com.android.settings.widget.RadioButtonPickerFragment; import com.android.settings.widget.RadioButtonPreference; import com.android.settings.wrapper.IPackageManagerWrapper; import com.android.settingslib.accessibility.AccessibilityUtils; import com.android.settingslib.wrapper.PackageManagerWrapper; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * Fragment for picking accessibility shortcut service */ public class ShortcutServicePickerFragment extends DefaultAppPickerFragment { public class ShortcutServicePickerFragment extends RadioButtonPickerFragment { @Override public int getMetricsCategory() { Loading @@ -60,22 +71,29 @@ public class ShortcutServicePickerFragment extends DefaultAppPickerFragment { } @Override protected List<? extends DefaultAppInfo> getCandidates() { protected List<? extends CandidateInfo> getCandidates() { final Context context = getContext(); final PackageManager pm = context.getPackageManager(); final AccessibilityManager accessibilityManager = context .getSystemService(AccessibilityManager.class); final List<AccessibilityServiceInfo> installedServices = accessibilityManager.getInstalledAccessibilityServiceList(); final int numInstalledServices = installedServices.size(); final PackageManagerWrapper pmw = new PackageManagerWrapper(context.getPackageManager()); List<DefaultAppInfo> candidates = new ArrayList<>(numInstalledServices); final List<CandidateInfo> candidates = new ArrayList<>(numInstalledServices); Map<ComponentName, ToggleableFrameworkFeatureInfo> frameworkFeatureInfoMap = AccessibilityShortcutController.getFrameworkShortcutFeaturesMap(); for (ComponentName componentName : frameworkFeatureInfoMap.keySet()) { // Lookup icon candidates.add(new FrameworkCandidateInfo(frameworkFeatureInfoMap.get(componentName), R.drawable.empty_icon, componentName.flattenToString())); } for (int i = 0; i < numInstalledServices; i++) { AccessibilityServiceInfo installedServiceInfo = installedServices.get(i); candidates.add(new DefaultAppInfo(context, mPm, UserHandle.myUserId(), final AccessibilityServiceInfo installedServiceInfo = installedServices.get(i); candidates.add(new DefaultAppInfo(context, pmw, UserHandle.myUserId(), installedServiceInfo.getComponentName(), (String) installedServiceInfo.loadSummary(mPm.getPackageManager()), true /* enabled */)); (String) installedServiceInfo.loadSummary(pm), true /* enabled */)); } return candidates; Loading Loading @@ -105,13 +123,21 @@ public class ShortcutServicePickerFragment extends DefaultAppPickerFragment { public void onRadioButtonClicked(RadioButtonPreference selected) { final String selectedKey = selected.getKey(); final Activity activity = getActivity(); if (TextUtils.isEmpty(selectedKey)) { super.onRadioButtonClicked(selected); } else if (activity != null) { final DialogFragment fragment = ConfirmationDialogFragment.newInstance( this, selectedKey); fragment.show(activity.getFragmentManager(), ConfirmationDialogFragment.TAG); } else { final ComponentName selectedComponent = ComponentName.unflattenFromString(selectedKey); if (AccessibilityShortcutController.getFrameworkShortcutFeaturesMap() .containsKey(selectedComponent)) { // This is a framework feature. It doesn't need to be confirmed. onRadioButtonConfirmed(selectedKey); } else { final Activity activity = getActivity(); if (activity != null) { ConfirmationDialogFragment.newInstance(this, selectedKey) .show(activity.getFragmentManager(), ConfirmationDialogFragment.TAG); } } } } Loading Loading @@ -156,11 +182,40 @@ public class ShortcutServicePickerFragment extends DefaultAppPickerFragment { @Override public void onClick(DialogInterface dialog, int which) { final Fragment fragment = getTargetFragment(); if ((which == BUTTON_POSITIVE) && (fragment instanceof DefaultAppPickerFragment)) { if ((which == BUTTON_POSITIVE) && (fragment instanceof ShortcutServicePickerFragment)) { final Bundle bundle = getArguments(); ((ShortcutServicePickerFragment) fragment).onServiceConfirmed( bundle.getString(EXTRA_KEY)); } } } private class FrameworkCandidateInfo extends CandidateInfo { ToggleableFrameworkFeatureInfo mToggleableFrameworkFeatureInfo; int mIconResId; String mKey; public FrameworkCandidateInfo( ToggleableFrameworkFeatureInfo frameworkFeatureInfo, int iconResId, String key) { super(true /* enabled */); mToggleableFrameworkFeatureInfo = frameworkFeatureInfo; mIconResId = iconResId; mKey = key; } @Override public CharSequence loadLabel() { return mToggleableFrameworkFeatureInfo.getLabel(getContext()); } @Override public Drawable loadIcon() { return getContext().getDrawable(mIconResId); } @Override public String getKey() { return mKey; } } } Loading
src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java +28 −7 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.settings.accessibility; import android.accessibilityservice.AccessibilityServiceInfo; import android.annotation.Nullable; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; Loading @@ -27,6 +28,7 @@ import android.support.v7.preference.Preference; import android.view.accessibility.AccessibilityManager; import android.widget.Switch; import com.android.internal.accessibility.AccessibilityShortcutController; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; import com.android.settings.search.BaseSearchIndexProvider; Loading Loading @@ -87,7 +89,7 @@ public class AccessibilityShortcutPreferenceFragment extends ToggleFeaturePrefer super.onInstallSwitchBarToggleSwitch(); mSwitchBar.addOnSwitchChangeListener((Switch switchView, boolean enabled) -> { Context context = getContext(); if (enabled && (getServiceInfo(context) == null)) { if (enabled && !shortcutFeatureAvailable(context)) { // If no service is configured, we'll disable the shortcut shortly. Give the // user a chance to select a service. We'll update the preferences when we resume. Settings.Secure.putInt( Loading @@ -110,7 +112,7 @@ public class AccessibilityShortcutPreferenceFragment extends ToggleFeaturePrefer ContentResolver cr = getContentResolver(); Context context = getContext(); mServicePreference.setSummary(getServiceName(context)); if (getServiceInfo(context) == null) { if (!shortcutFeatureAvailable(context)) { // If no service is configured, make sure the overall shortcut is turned off Settings.Secure.putInt( getContentResolver(), Settings.Secure.ACCESSIBILITY_SHORTCUT_ENABLED, 0); Loading @@ -132,19 +134,38 @@ public class AccessibilityShortcutPreferenceFragment extends ToggleFeaturePrefer * @return The name of the service or a string saying that none is selected. */ public static CharSequence getServiceName(Context context) { if (!shortcutFeatureAvailable(context)) { return context.getString(R.string.accessibility_no_service_selected); } AccessibilityServiceInfo shortcutServiceInfo = getServiceInfo(context); if (shortcutServiceInfo != null) { return shortcutServiceInfo.getResolveInfo().loadLabel(context.getPackageManager()); } return context.getString(R.string.accessibility_no_service_selected); return AccessibilityShortcutController.getFrameworkShortcutFeaturesMap() .get(getShortcutComponent(context)).getLabel(context); } private static AccessibilityServiceInfo getServiceInfo(Context context) { ComponentName shortcutServiceName = ComponentName.unflattenFromString( AccessibilityUtils.getShortcutTargetServiceComponentNameString( context, UserHandle.myUserId())); return AccessibilityManager.getInstance(context) .getInstalledServiceInfoWithComponentName(shortcutServiceName); .getInstalledServiceInfoWithComponentName(getShortcutComponent(context)); } private static boolean shortcutFeatureAvailable(Context context) { ComponentName shortcutFeature = getShortcutComponent(context); if (shortcutFeature == null) return false; if (AccessibilityShortcutController.getFrameworkShortcutFeaturesMap() .containsKey(shortcutFeature)) { return true; } return getServiceInfo(context) != null; } private static @Nullable ComponentName getShortcutComponent(Context context) { String componentNameString = AccessibilityUtils.getShortcutTargetServiceComponentNameString( context, UserHandle.myUserId()); if (componentNameString == null) return null; return ComponentName.unflattenFromString(componentNameString); } public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = Loading
src/com/android/settings/accessibility/ShortcutServicePickerFragment.java +70 −15 Original line number Diff line number Diff line Loading @@ -25,29 +25,40 @@ import android.app.Fragment; import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; import android.content.pm.ApplicationInfo; import android.content.pm.ComponentInfo; import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; import android.os.UserHandle; import android.provider.Settings; import android.text.TextUtils; import android.util.IconDrawableFactory; import android.view.accessibility.AccessibilityManager; import com.android.internal.accessibility.AccessibilityShortcutController; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.accessibility.AccessibilityShortcutController.ToggleableFrameworkFeatureInfo; import com.android.settings.R; import com.android.settings.applications.defaultapps.DefaultAppInfo; import com.android.settings.applications.defaultapps.DefaultAppPickerFragment; import com.android.settings.core.instrumentation.InstrumentedDialogFragment; import com.android.settings.widget.RadioButtonPickerFragment; import com.android.settings.widget.RadioButtonPreference; import com.android.settings.wrapper.IPackageManagerWrapper; import com.android.settingslib.accessibility.AccessibilityUtils; import com.android.settingslib.wrapper.PackageManagerWrapper; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * Fragment for picking accessibility shortcut service */ public class ShortcutServicePickerFragment extends DefaultAppPickerFragment { public class ShortcutServicePickerFragment extends RadioButtonPickerFragment { @Override public int getMetricsCategory() { Loading @@ -60,22 +71,29 @@ public class ShortcutServicePickerFragment extends DefaultAppPickerFragment { } @Override protected List<? extends DefaultAppInfo> getCandidates() { protected List<? extends CandidateInfo> getCandidates() { final Context context = getContext(); final PackageManager pm = context.getPackageManager(); final AccessibilityManager accessibilityManager = context .getSystemService(AccessibilityManager.class); final List<AccessibilityServiceInfo> installedServices = accessibilityManager.getInstalledAccessibilityServiceList(); final int numInstalledServices = installedServices.size(); final PackageManagerWrapper pmw = new PackageManagerWrapper(context.getPackageManager()); List<DefaultAppInfo> candidates = new ArrayList<>(numInstalledServices); final List<CandidateInfo> candidates = new ArrayList<>(numInstalledServices); Map<ComponentName, ToggleableFrameworkFeatureInfo> frameworkFeatureInfoMap = AccessibilityShortcutController.getFrameworkShortcutFeaturesMap(); for (ComponentName componentName : frameworkFeatureInfoMap.keySet()) { // Lookup icon candidates.add(new FrameworkCandidateInfo(frameworkFeatureInfoMap.get(componentName), R.drawable.empty_icon, componentName.flattenToString())); } for (int i = 0; i < numInstalledServices; i++) { AccessibilityServiceInfo installedServiceInfo = installedServices.get(i); candidates.add(new DefaultAppInfo(context, mPm, UserHandle.myUserId(), final AccessibilityServiceInfo installedServiceInfo = installedServices.get(i); candidates.add(new DefaultAppInfo(context, pmw, UserHandle.myUserId(), installedServiceInfo.getComponentName(), (String) installedServiceInfo.loadSummary(mPm.getPackageManager()), true /* enabled */)); (String) installedServiceInfo.loadSummary(pm), true /* enabled */)); } return candidates; Loading Loading @@ -105,13 +123,21 @@ public class ShortcutServicePickerFragment extends DefaultAppPickerFragment { public void onRadioButtonClicked(RadioButtonPreference selected) { final String selectedKey = selected.getKey(); final Activity activity = getActivity(); if (TextUtils.isEmpty(selectedKey)) { super.onRadioButtonClicked(selected); } else if (activity != null) { final DialogFragment fragment = ConfirmationDialogFragment.newInstance( this, selectedKey); fragment.show(activity.getFragmentManager(), ConfirmationDialogFragment.TAG); } else { final ComponentName selectedComponent = ComponentName.unflattenFromString(selectedKey); if (AccessibilityShortcutController.getFrameworkShortcutFeaturesMap() .containsKey(selectedComponent)) { // This is a framework feature. It doesn't need to be confirmed. onRadioButtonConfirmed(selectedKey); } else { final Activity activity = getActivity(); if (activity != null) { ConfirmationDialogFragment.newInstance(this, selectedKey) .show(activity.getFragmentManager(), ConfirmationDialogFragment.TAG); } } } } Loading Loading @@ -156,11 +182,40 @@ public class ShortcutServicePickerFragment extends DefaultAppPickerFragment { @Override public void onClick(DialogInterface dialog, int which) { final Fragment fragment = getTargetFragment(); if ((which == BUTTON_POSITIVE) && (fragment instanceof DefaultAppPickerFragment)) { if ((which == BUTTON_POSITIVE) && (fragment instanceof ShortcutServicePickerFragment)) { final Bundle bundle = getArguments(); ((ShortcutServicePickerFragment) fragment).onServiceConfirmed( bundle.getString(EXTRA_KEY)); } } } private class FrameworkCandidateInfo extends CandidateInfo { ToggleableFrameworkFeatureInfo mToggleableFrameworkFeatureInfo; int mIconResId; String mKey; public FrameworkCandidateInfo( ToggleableFrameworkFeatureInfo frameworkFeatureInfo, int iconResId, String key) { super(true /* enabled */); mToggleableFrameworkFeatureInfo = frameworkFeatureInfo; mIconResId = iconResId; mKey = key; } @Override public CharSequence loadLabel() { return mToggleableFrameworkFeatureInfo.getLabel(getContext()); } @Override public Drawable loadIcon() { return getContext().getDrawable(mIconResId); } @Override public String getKey() { return mKey; } } }