Home | History | Annotate | Download | only in accessibility
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package com.android.settings.accessibility;
     17 
     18 import static android.content.DialogInterface.BUTTON_POSITIVE;
     19 
     20 import static com.android.settings.Utils.setOverlayAllowed;
     21 
     22 import android.accessibilityservice.AccessibilityServiceInfo;
     23 import android.app.Activity;
     24 import android.app.Dialog;
     25 import android.app.DialogFragment;
     26 import android.app.Fragment;
     27 import android.content.ComponentName;
     28 import android.content.DialogInterface;
     29 import android.os.Binder;
     30 import android.os.Bundle;
     31 import android.os.IBinder;
     32 import android.os.UserHandle;
     33 import android.provider.Settings;
     34 import android.text.TextUtils;
     35 import android.view.accessibility.AccessibilityManager;
     36 
     37 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
     38 import com.android.settings.applications.defaultapps.DefaultAppInfo;
     39 import com.android.settings.applications.defaultapps.DefaultAppPickerFragment;
     40 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
     41 import com.android.settings.widget.RadioButtonPreference;
     42 import com.android.settingslib.accessibility.AccessibilityUtils;
     43 
     44 import java.util.ArrayList;
     45 import java.util.List;
     46 
     47 /**
     48  * Fragment for picking accessibility shortcut service
     49  */
     50 public class ShortcutServicePickerFragment extends DefaultAppPickerFragment {
     51 
     52     @Override
     53     public int getMetricsCategory() {
     54         return MetricsEvent.ACCESSIBILITY_TOGGLE_GLOBAL_GESTURE;
     55     }
     56 
     57     @Override
     58     protected List<? extends DefaultAppInfo> getCandidates() {
     59         final AccessibilityManager accessibilityManager = getContext()
     60                 .getSystemService(AccessibilityManager.class);
     61         final List<AccessibilityServiceInfo> installedServices =
     62                 accessibilityManager.getInstalledAccessibilityServiceList();
     63         final int numInstalledServices = installedServices.size();
     64 
     65         List<DefaultAppInfo> candidates = new ArrayList<>(numInstalledServices);
     66         for (int i = 0; i < numInstalledServices; i++) {
     67             AccessibilityServiceInfo installedServiceInfo = installedServices.get(i);
     68             candidates.add(new DefaultAppInfo(mPm,
     69                     UserHandle.myUserId(),
     70                     installedServiceInfo.getComponentName(),
     71                     (String) installedServiceInfo.loadSummary(mPm.getPackageManager()),
     72                     true /* enabled */));
     73         }
     74 
     75         return candidates;
     76     }
     77 
     78     @Override
     79     protected String getDefaultKey() {
     80         String shortcutServiceString = AccessibilityUtils
     81                 .getShortcutTargetServiceComponentNameString(getContext(), UserHandle.myUserId());
     82         if (shortcutServiceString != null) {
     83             ComponentName shortcutName = ComponentName.unflattenFromString(shortcutServiceString);
     84             if (shortcutName != null) {
     85                 return shortcutName.flattenToString();
     86             }
     87         }
     88         return null;
     89     }
     90 
     91     @Override
     92     protected boolean setDefaultKey(String key) {
     93         Settings.Secure.putString(getContext().getContentResolver(),
     94                 Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, key);
     95         return true;
     96     }
     97 
     98     @Override
     99     public void onRadioButtonClicked(RadioButtonPreference selected) {
    100         final String selectedKey = selected.getKey();
    101 
    102         final Activity activity = getActivity();
    103         if (TextUtils.isEmpty(selectedKey)) {
    104             super.onRadioButtonClicked(selected);
    105         } else if (activity != null) {
    106             final DialogFragment fragment = ConfirmationDialogFragment.newInstance(
    107                     this, selectedKey);
    108             fragment.show(activity.getFragmentManager(), ConfirmationDialogFragment.TAG);
    109         }
    110     }
    111 
    112     private void onServiceConfirmed(String serviceKey) {
    113         onRadioButtonConfirmed(serviceKey);
    114     }
    115 
    116     public static class ConfirmationDialogFragment extends InstrumentedDialogFragment
    117             implements DialogInterface.OnClickListener {
    118         private static final String EXTRA_KEY = "extra_key";
    119         private static final String TAG = "ConfirmationDialogFragment";
    120         private IBinder mToken;
    121 
    122         public static ConfirmationDialogFragment newInstance(ShortcutServicePickerFragment parent,
    123                 String key) {
    124             final ConfirmationDialogFragment fragment = new ConfirmationDialogFragment();
    125             final Bundle argument = new Bundle();
    126             argument.putString(EXTRA_KEY, key);
    127             fragment.setArguments(argument);
    128             fragment.setTargetFragment(parent, 0);
    129             fragment.mToken = new Binder();
    130             return fragment;
    131         }
    132 
    133         @Override
    134         public int getMetricsCategory() {
    135             return MetricsEvent.ACCESSIBILITY_TOGGLE_GLOBAL_GESTURE;
    136         }
    137 
    138         @Override
    139         public Dialog onCreateDialog(Bundle savedInstanceState) {
    140             final Bundle bundle = getArguments();
    141             final String key = bundle.getString(EXTRA_KEY);
    142             final ComponentName serviceComponentName = ComponentName.unflattenFromString(key);
    143             final AccessibilityManager accessibilityManager = getActivity()
    144                     .getSystemService(AccessibilityManager.class);
    145             AccessibilityServiceInfo info = accessibilityManager
    146                     .getInstalledServiceInfoWithComponentName(serviceComponentName);
    147             return AccessibilityServiceWarning.createCapabilitiesDialog(getActivity(), info, this);
    148         }
    149 
    150         @Override
    151         public void onResume() {
    152             super.onResume();
    153             if (mToken != null) {
    154                 setOverlayAllowed(getActivity(), mToken, false);
    155             }
    156         }
    157 
    158         @Override
    159         public void onPause() {
    160             super.onPause();
    161             if (mToken != null) {
    162                 setOverlayAllowed(getActivity(), mToken, true);
    163             }
    164         }
    165 
    166         @Override
    167         public void onClick(DialogInterface dialog, int which) {
    168             final Fragment fragment = getTargetFragment();
    169             if ((which == BUTTON_POSITIVE) && (fragment instanceof DefaultAppPickerFragment)) {
    170                 final Bundle bundle = getArguments();
    171                 ((ShortcutServicePickerFragment) fragment).onServiceConfirmed(
    172                         bundle.getString(EXTRA_KEY));
    173             }
    174         }
    175     }
    176 }
    177