blob: 31ccb6c32babd1cb85244b88c26a3a5565791ce5 [file] [log] [blame]
Peter_Liangdfe6f9232020-03-05 12:04:13 +08001/*
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
17package com.android.internal.accessibility.util;
18import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_BUTTON;
19import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY;
20
21import static com.android.internal.accessibility.common.ShortcutConstants.SERVICES_SEPARATOR;
22import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
23
24import android.annotation.NonNull;
25import android.content.Context;
26import android.provider.Settings;
27import android.text.TextUtils;
Peter_Liangfbad5482020-04-08 19:32:53 +080028import android.view.accessibility.AccessibilityManager;
Peter_Liangdfe6f9232020-03-05 12:04:13 +080029import android.view.accessibility.AccessibilityManager.ShortcutType;
30
Peter_Liangfbad5482020-04-08 19:32:53 +080031import java.util.List;
Peter_Liangdfe6f9232020-03-05 12:04:13 +080032import java.util.StringJoiner;
33
34/**
35 * Collection of utilities for accessibility shortcut.
36 */
37public final class ShortcutUtils {
38 private ShortcutUtils() {}
39
40 private static final TextUtils.SimpleStringSplitter sStringColonSplitter =
41 new TextUtils.SimpleStringSplitter(SERVICES_SEPARATOR);
42
43 /**
Peter_Liang8b7c9da2020-04-08 16:56:59 +080044 * Opts in component id into colon-separated {@link UserShortcutType}
45 * key's string from Settings.
Peter_Liang1e20bc42020-03-05 20:18:16 +080046 *
47 * @param context The current context.
48 * @param shortcutType The preferred shortcut type user selected.
Peter_Liang8b7c9da2020-04-08 16:56:59 +080049 * @param componentId The component id that need to be opted in Settings.
Peter_Liang1e20bc42020-03-05 20:18:16 +080050 */
51 public static void optInValueToSettings(Context context, @UserShortcutType int shortcutType,
Peter_Liang8b7c9da2020-04-08 16:56:59 +080052 @NonNull String componentId) {
Peter_Liang1e20bc42020-03-05 20:18:16 +080053 final StringJoiner joiner = new StringJoiner(String.valueOf(SERVICES_SEPARATOR));
54 final String targetKey = convertToKey(shortcutType);
55 final String targetString = Settings.Secure.getString(context.getContentResolver(),
56 targetKey);
57
Peter_Liang8b7c9da2020-04-08 16:56:59 +080058 if (isComponentIdExistingInSettings(context, shortcutType, componentId)) {
Peter_Liang1e20bc42020-03-05 20:18:16 +080059 return;
60 }
61
62 if (!TextUtils.isEmpty(targetString)) {
63 joiner.add(targetString);
64 }
65 joiner.add(componentId);
66
67 Settings.Secure.putString(context.getContentResolver(), targetKey, joiner.toString());
68 }
69
70 /**
Peter_Liang8b7c9da2020-04-08 16:56:59 +080071 * Opts out of component id into colon-separated {@link UserShortcutType} key's string from
72 * Settings.
Peter_Liangdfe6f9232020-03-05 12:04:13 +080073 *
74 * @param context The current context.
75 * @param shortcutType The preferred shortcut type user selected.
Peter_Liang8b7c9da2020-04-08 16:56:59 +080076 * @param componentId The component id that need to be opted out of Settings.
Peter_Liangdfe6f9232020-03-05 12:04:13 +080077 */
78 public static void optOutValueFromSettings(
Peter_Liang8b7c9da2020-04-08 16:56:59 +080079 Context context, @UserShortcutType int shortcutType, @NonNull String componentId) {
Peter_Liangdfe6f9232020-03-05 12:04:13 +080080 final StringJoiner joiner = new StringJoiner(String.valueOf(SERVICES_SEPARATOR));
81 final String targetsKey = convertToKey(shortcutType);
82 final String targetsValue = Settings.Secure.getString(context.getContentResolver(),
83 targetsKey);
84
85 if (TextUtils.isEmpty(targetsValue)) {
86 return;
87 }
88
89 sStringColonSplitter.setString(targetsValue);
90 while (sStringColonSplitter.hasNext()) {
91 final String id = sStringColonSplitter.next();
92 if (TextUtils.isEmpty(id) || componentId.equals(id)) {
93 continue;
94 }
95 joiner.add(id);
96 }
97
98 Settings.Secure.putString(context.getContentResolver(), targetsKey, joiner.toString());
99 }
100
101 /**
Peter_Liang8b7c9da2020-04-08 16:56:59 +0800102 * Returns if component id existed in Settings.
Peter_Liangdfe6f9232020-03-05 12:04:13 +0800103 *
104 * @param context The current context.
105 * @param shortcutType The preferred shortcut type user selected.
106 * @param componentId The component id that need to be checked existed in Settings.
Peter_Liang8b7c9da2020-04-08 16:56:59 +0800107 * @return {@code true} if component id existed in Settings.
Peter_Liangdfe6f9232020-03-05 12:04:13 +0800108 */
Peter_Liang8b7c9da2020-04-08 16:56:59 +0800109 public static boolean isComponentIdExistingInSettings(Context context,
110 @UserShortcutType int shortcutType, @NonNull String componentId) {
Peter_Liangdfe6f9232020-03-05 12:04:13 +0800111 final String targetKey = convertToKey(shortcutType);
112 final String targetString = Settings.Secure.getString(context.getContentResolver(),
113 targetKey);
114
115 if (TextUtils.isEmpty(targetString)) {
116 return false;
117 }
118
119 sStringColonSplitter.setString(targetString);
120 while (sStringColonSplitter.hasNext()) {
121 final String id = sStringColonSplitter.next();
122 if (componentId.equals(id)) {
123 return true;
124 }
125 }
126
127 return false;
128 }
129
130 /**
Peter_Liangfbad5482020-04-08 19:32:53 +0800131 * Returns if a {@code shortcutType} shortcut contains {@code componentId}.
132 *
133 * @param context The current context.
134 * @param shortcutType The preferred shortcut type user selected.
135 * @param componentId The component id that need to be checked.
136 * @return {@code true} if a component id is contained.
137 */
138 public static boolean isShortcutContained(Context context, @ShortcutType int shortcutType,
139 @NonNull String componentId) {
menghanli3cba1dc2020-03-18 20:54:27 +0800140 final AccessibilityManager am = (AccessibilityManager) context.getSystemService(
141 Context.ACCESSIBILITY_SERVICE);
Peter_Liangfbad5482020-04-08 19:32:53 +0800142 final List<String> requiredTargets = am.getAccessibilityShortcutTargets(shortcutType);
143 return requiredTargets.contains(componentId);
144 }
145
146 /**
Peter_Liang8b7c9da2020-04-08 16:56:59 +0800147 * Converts {@link UserShortcutType} to {@link Settings.Secure} key.
Peter_Liangdfe6f9232020-03-05 12:04:13 +0800148 *
149 * @param type The shortcut type.
150 * @return Mapping key in Settings.
151 */
152 public static String convertToKey(@UserShortcutType int type) {
153 switch (type) {
154 case UserShortcutType.SOFTWARE:
Peter_Liangb8bf55c2020-04-08 22:12:24 +0800155 return Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS;
Peter_Liangdfe6f9232020-03-05 12:04:13 +0800156 case UserShortcutType.HARDWARE:
157 return Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE;
158 case UserShortcutType.TRIPLETAP:
159 return Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED;
160 default:
161 throw new IllegalArgumentException(
162 "Unsupported user shortcut type: " + type);
163 }
164 }
165
166 /**
167 * Converts {@link ShortcutType} to {@link UserShortcutType}.
168 *
169 * @param type The shortcut type.
Peter_Liang8b7c9da2020-04-08 16:56:59 +0800170 * @return Mapping type from {@link UserShortcutType}.
Peter_Liangdfe6f9232020-03-05 12:04:13 +0800171 */
172 public static @UserShortcutType int convertToUserType(@ShortcutType int type) {
173 switch (type) {
174 case ACCESSIBILITY_BUTTON:
175 return UserShortcutType.SOFTWARE;
176 case ACCESSIBILITY_SHORTCUT_KEY:
177 return UserShortcutType.HARDWARE;
178 default:
179 throw new IllegalArgumentException(
180 "Unsupported shortcut type:" + type);
181 }
182 }
183}