• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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.internal.accessibility.dialog;
17 
18 import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_BUTTON;
19 import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY;
20 import static android.view.accessibility.AccessibilityManager.ShortcutType;
21 
22 import static com.android.internal.accessibility.common.ShortcutConstants.ShortcutMenuMode;
23 import static com.android.internal.accessibility.dialog.AccessibilityTargetHelper.createEnableDialogContentView;
24 import static com.android.internal.accessibility.dialog.AccessibilityTargetHelper.getInstalledTargets;
25 import static com.android.internal.accessibility.dialog.AccessibilityTargetHelper.getTargets;
26 import static com.android.internal.accessibility.util.AccessibilityUtils.isUserSetupCompleted;
27 
28 import android.annotation.Nullable;
29 import android.app.Activity;
30 import android.app.AlertDialog;
31 import android.content.DialogInterface;
32 import android.content.res.TypedArray;
33 import android.os.Bundle;
34 import android.view.View;
35 import android.view.Window;
36 import android.widget.AdapterView;
37 
38 import com.android.internal.R;
39 
40 import java.util.ArrayList;
41 import java.util.List;
42 
43 /**
44  * Activity used to display various targets related to accessibility service, accessibility
45  * activity or allowlisting feature for volume key shortcut.
46  */
47 public class AccessibilityShortcutChooserActivity extends Activity {
48     @ShortcutType
49     private final int mShortcutType = ACCESSIBILITY_SHORTCUT_KEY;
50     private final List<AccessibilityTarget> mTargets = new ArrayList<>();
51     private AlertDialog mMenuDialog;
52     private AlertDialog mPermissionDialog;
53     private ShortcutTargetAdapter mTargetAdapter;
54 
55     @Override
onCreate(@ullable Bundle savedInstanceState)56     protected void onCreate(@Nullable Bundle savedInstanceState) {
57         super.onCreate(savedInstanceState);
58 
59         final TypedArray theme = getTheme().obtainStyledAttributes(android.R.styleable.Theme);
60         if (!theme.getBoolean(android.R.styleable.Theme_windowNoTitle, /* defValue= */ false)) {
61             requestWindowFeature(Window.FEATURE_NO_TITLE);
62         }
63 
64         mTargets.addAll(getTargets(this, mShortcutType));
65         mTargetAdapter = new ShortcutTargetAdapter(mTargets);
66         mMenuDialog = createMenuDialog();
67         mMenuDialog.setOnShowListener(dialog -> updateDialogListeners());
68         mMenuDialog.show();
69     }
70 
71     @Override
onDestroy()72     protected void onDestroy() {
73         mMenuDialog.dismiss();
74         super.onDestroy();
75     }
76 
onTargetSelected(AdapterView<?> parent, View view, int position, long id)77     private void onTargetSelected(AdapterView<?> parent, View view, int position, long id) {
78         final AccessibilityTarget target = mTargets.get(position);
79         target.onSelected();
80         mMenuDialog.dismiss();
81     }
82 
onTargetChecked(AdapterView<?> parent, View view, int position, long id)83     private void onTargetChecked(AdapterView<?> parent, View view, int position, long id) {
84         final AccessibilityTarget target = mTargets.get(position);
85 
86         if ((target instanceof AccessibilityServiceTarget) && !target.isShortcutEnabled()) {
87             mPermissionDialog = new AlertDialog.Builder(this)
88                     .setView(createEnableDialogContentView(this,
89                             (AccessibilityServiceTarget) target,
90                             v -> {
91                                 mPermissionDialog.dismiss();
92                                 mTargetAdapter.notifyDataSetChanged();
93                             },
94                             v -> mPermissionDialog.dismiss()))
95                     .create();
96             mPermissionDialog.show();
97             return;
98         }
99 
100         target.onCheckedChanged(!target.isShortcutEnabled());
101         mTargetAdapter.notifyDataSetChanged();
102     }
103 
onDoneButtonClicked()104     private void onDoneButtonClicked() {
105         mTargets.clear();
106         mTargets.addAll(getTargets(this, mShortcutType));
107         if (mTargets.isEmpty()) {
108             mMenuDialog.dismiss();
109             return;
110         }
111 
112         mTargetAdapter.setShortcutMenuMode(ShortcutMenuMode.LAUNCH);
113         mTargetAdapter.notifyDataSetChanged();
114 
115         mMenuDialog.getButton(DialogInterface.BUTTON_POSITIVE).setText(
116                 getString(R.string.edit_accessibility_shortcut_menu_button));
117 
118         updateDialogListeners();
119     }
120 
onEditButtonClicked()121     private void onEditButtonClicked() {
122         mTargets.clear();
123         mTargets.addAll(getInstalledTargets(this, mShortcutType));
124         mTargetAdapter.setShortcutMenuMode(ShortcutMenuMode.EDIT);
125         mTargetAdapter.notifyDataSetChanged();
126 
127         mMenuDialog.getButton(DialogInterface.BUTTON_POSITIVE).setText(
128                 getString(R.string.done_accessibility_shortcut_menu_button));
129 
130         updateDialogListeners();
131     }
132 
updateDialogListeners()133     private void updateDialogListeners() {
134         final boolean isEditMenuMode =
135                 mTargetAdapter.getShortcutMenuMode() == ShortcutMenuMode.EDIT;
136         final int selectDialogTitleId = R.string.accessibility_select_shortcut_menu_title;
137         final int editDialogTitleId =
138                 mShortcutType == ACCESSIBILITY_BUTTON
139                         ? R.string.accessibility_edit_shortcut_menu_button_title
140                         : R.string.accessibility_edit_shortcut_menu_volume_title;
141 
142         mMenuDialog.setTitle(getString(isEditMenuMode ? editDialogTitleId : selectDialogTitleId));
143         mMenuDialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(
144                 isEditMenuMode ? view -> onDoneButtonClicked() : view -> onEditButtonClicked());
145         mMenuDialog.getListView().setOnItemClickListener(
146                 isEditMenuMode ? this::onTargetChecked : this::onTargetSelected);
147     }
148 
createMenuDialog()149     private AlertDialog createMenuDialog() {
150         final String dialogTitle =
151                 getString(R.string.accessibility_select_shortcut_menu_title);
152 
153         final AlertDialog.Builder builder = new AlertDialog.Builder(this)
154                 .setTitle(dialogTitle)
155                 .setAdapter(mTargetAdapter, /* listener= */ null)
156                 .setOnDismissListener(dialog -> finish());
157 
158         if (isUserSetupCompleted(this)) {
159             final String positiveButtonText =
160                     getString(R.string.edit_accessibility_shortcut_menu_button);
161             builder.setPositiveButton(positiveButtonText, /* listener= */ null);
162         }
163 
164         return builder.create();
165     }
166 }
167