ShortcutServicePickerFragment.java revision 2e2dbfe549d6803483d509b62538a875de433151
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 */
16package com.android.settings.accessibility;
17
18import static android.content.DialogInterface.BUTTON_POSITIVE;
19import static com.android.settings.Utils.setOverlayAllowed;
20
21import android.accessibilityservice.AccessibilityServiceInfo;
22import android.app.Activity;
23import android.app.Dialog;
24import android.app.DialogFragment;
25import android.app.Fragment;
26import android.content.ComponentName;
27import android.content.DialogInterface;
28import android.os.Binder;
29import android.os.Bundle;
30import android.os.IBinder;
31import android.os.UserHandle;
32import android.provider.Settings;
33import android.text.TextUtils;
34import android.view.accessibility.AccessibilityManager;
35
36import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
37import com.android.settings.applications.defaultapps.DefaultAppInfo;
38import com.android.settings.applications.defaultapps.DefaultAppPickerFragment;
39import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
40import com.android.settings.widget.RadioButtonPreference;
41import com.android.settingslib.accessibility.AccessibilityUtils;
42
43import java.util.ArrayList;
44import java.util.List;
45
46/**
47 * Fragment for picking accessibility shortcut service
48 */
49public class ShortcutServicePickerFragment extends DefaultAppPickerFragment {
50
51    @Override
52    public int getMetricsCategory() {
53        return MetricsEvent.ACCESSIBILITY_TOGGLE_GLOBAL_GESTURE;
54    }
55
56    @Override
57    protected List<? extends DefaultAppInfo> getCandidates() {
58        final AccessibilityManager accessibilityManager = getContext()
59                .getSystemService(AccessibilityManager.class);
60        final List<AccessibilityServiceInfo> installedServices =
61                accessibilityManager.getInstalledAccessibilityServiceList();
62        final int numInstalledServices = installedServices.size();
63
64        List<DefaultAppInfo> candidates = new ArrayList<>(numInstalledServices);
65        for (int i = 0; i < numInstalledServices; i++) {
66            AccessibilityServiceInfo installedServiceInfo = installedServices.get(i);
67            candidates.add(new DefaultAppInfo(mPm,
68                    UserHandle.myUserId(),
69                    installedServiceInfo.getComponentName(),
70                    (String) installedServiceInfo.loadSummary(mPm.getPackageManager()),
71                    true /* enabled */));
72        }
73
74        return candidates;
75    }
76
77    @Override
78    protected String getDefaultKey() {
79        String shortcutServiceString = AccessibilityUtils
80                .getShortcutTargetServiceComponentNameString(getContext(), UserHandle.myUserId());
81        if (shortcutServiceString != null) {
82            ComponentName shortcutName = ComponentName.unflattenFromString(shortcutServiceString);
83            if (shortcutName != null) {
84                return shortcutName.flattenToString();
85            }
86        }
87        return null;
88    }
89
90    @Override
91    protected boolean setDefaultKey(String key) {
92        Settings.Secure.putString(getContext().getContentResolver(),
93                Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, key);
94        return true;
95    }
96
97    @Override
98    public void onRadioButtonClicked(RadioButtonPreference selected) {
99        final String selectedKey = selected.getKey();
100
101        final Activity activity = getActivity();
102        if (TextUtils.isEmpty(selectedKey)) {
103            super.onRadioButtonClicked(selected);
104        } else if (activity != null) {
105            final DialogFragment fragment = ConfirmationDialogFragment.newInstance(
106                    this, selectedKey);
107            fragment.show(activity.getFragmentManager(), ConfirmationDialogFragment.TAG);
108        }
109    }
110
111    private void onServiceConfirmed(String serviceKey) {
112        onRadioButtonConfirmed(serviceKey);
113    }
114
115    public static class ConfirmationDialogFragment extends InstrumentedDialogFragment
116            implements DialogInterface.OnClickListener {
117        private static final String EXTRA_KEY = "extra_key";
118        private static final String TAG = "ConfirmationDialogFragment";
119        private IBinder mToken;
120
121        public static ConfirmationDialogFragment newInstance(ShortcutServicePickerFragment parent,
122                String key) {
123            final ConfirmationDialogFragment fragment = new ConfirmationDialogFragment();
124            final Bundle argument = new Bundle();
125            argument.putString(EXTRA_KEY, key);
126            fragment.setArguments(argument);
127            fragment.setTargetFragment(parent, 0);
128            fragment.mToken = new Binder();
129            return fragment;
130        }
131
132        @Override
133        public int getMetricsCategory() {
134            return MetricsEvent.ACCESSIBILITY_TOGGLE_GLOBAL_GESTURE;
135        }
136
137        @Override
138        public Dialog onCreateDialog(Bundle savedInstanceState) {
139            final Bundle bundle = getArguments();
140            final String key = bundle.getString(EXTRA_KEY);
141            final ComponentName serviceComponentName = ComponentName.unflattenFromString(key);
142            final AccessibilityManager accessibilityManager = getActivity()
143                    .getSystemService(AccessibilityManager.class);
144            AccessibilityServiceInfo info = accessibilityManager
145                    .getInstalledServiceInfoWithComponentName(serviceComponentName);
146            return AccessibilityServiceWarning.createCapabilitiesDialog(getActivity(), info, this);
147        }
148
149        @Override
150        public void onResume() {
151            super.onResume();
152            if (mToken != null) {
153                setOverlayAllowed(getActivity(), mToken, false);
154            }
155        }
156
157        @Override
158        public void onPause() {
159            super.onPause();
160            if (mToken != null) {
161                setOverlayAllowed(getActivity(), mToken, true);
162            }
163        }
164
165        @Override
166        public void onClick(DialogInterface dialog, int which) {
167            final Fragment fragment = getTargetFragment();
168            if ((which == BUTTON_POSITIVE) && (fragment instanceof DefaultAppPickerFragment)) {
169                final Bundle bundle = getArguments();
170                ((ShortcutServicePickerFragment) fragment).onServiceConfirmed(
171                        bundle.getString(EXTRA_KEY));
172            }
173        }
174    }
175}
176