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