Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b9cf0d2a authored by Phil Weaver's avatar Phil Weaver
Browse files

Settings enable a11y shortcut framework features

Bug: 34621067
Test: Settings->Accessibility->Volume key shortcut
dialog now shows color inversion and color correction,
and selecting them works.
Change-Id: If7b4f55bd39fbd4c00b1ad95c6568a77e23c4e7e
parent 9ce491f2
Loading
Loading
Loading
Loading
+28 −7
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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(
@@ -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);
@@ -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 =
+70 −15
Original line number Diff line number Diff line
@@ -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() {
@@ -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;
@@ -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);
                }
            }
        }
    }

@@ -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;
        }
    }
}