• 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 
17 package com.android.settings.accessibility;
18 
19 import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.DEFAULT;
20 import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
21 
22 import android.content.ComponentName;
23 import android.content.Context;
24 import android.content.SharedPreferences;
25 import android.os.UserHandle;
26 import android.util.ArrayMap;
27 
28 import androidx.annotation.NonNull;
29 import androidx.annotation.VisibleForTesting;
30 
31 import com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
32 import com.android.internal.accessibility.util.ShortcutUtils;
33 
34 import java.util.HashSet;
35 import java.util.Map;
36 import java.util.Set;
37 
38 /** Static utility methods relating to {@link PreferredShortcut} */
39 public final class PreferredShortcuts {
40 
41     private static final String ACCESSIBILITY_PERF = "accessibility_prefs";
42     private static final String USER_SHORTCUT_TYPE = "user_shortcut_type";
43 
44     /**
45      * Retrieves the user preferred shortcut types for the given {@code componentName} from
46      * SharedPreferences. If the user doesn't have a preferred shortcut,
47      * {@link SOFTWARE} is returned.
48      *
49      * @param context       {@link Context} to access the {@link SharedPreferences}
50      * @param componentName Name of the service or activity, should be the format of {@link
51      *                      ComponentName#flattenToString()}.
52      * @return {@link UserShortcutType}
53      */
54     @UserShortcutType
retrieveUserShortcutType( @onNull Context context, @NonNull String componentName)55     public static int retrieveUserShortcutType(
56             @NonNull Context context, @NonNull String componentName) {
57         return retrieveUserShortcutType(
58                 context, componentName, SOFTWARE);
59     }
60 
61     /**
62      * Retrieves the user preferred shortcut types for the given {@code componentName} from
63      * SharedPreferences.
64      *
65      * @param context          {@link Context} to access the {@link SharedPreferences}
66      * @param componentName    Name of the service or activity, should be the format of {@link
67      *                         ComponentName#flattenToString()}.
68      * @param defaultTypes The default shortcut types to use if the user doesn't have a
69      *                         preferred shortcut.
70      * @return {@link UserShortcutType}
71      */
72     @UserShortcutType
retrieveUserShortcutType( @onNull Context context, @NonNull String componentName, @UserShortcutType int defaultTypes)73     public static int retrieveUserShortcutType(
74             @NonNull Context context,
75             @NonNull String componentName,
76             @UserShortcutType int defaultTypes) {
77 
78         // Create a mutable set to modify
79         final Set<String> info = new HashSet<>(getFromSharedPreferences(context));
80         info.removeIf(str -> !str.contains(componentName));
81 
82         if (info.isEmpty()) {
83             return defaultTypes;
84         }
85 
86         final String str = info.stream().findFirst().get();
87         final PreferredShortcut shortcut = PreferredShortcut.fromString(str);
88         return shortcut.getType();
89     }
90 
91     /**
92      * Saves a {@link PreferredShortcut} which containing {@link ComponentName#flattenToString()}
93      * and {@link UserShortcutType} in SharedPreferences.
94      *
95      * @param context  {@link Context} to access the {@link SharedPreferences}
96      * @param shortcut Contains {@link ComponentName#flattenToString()} and {@link UserShortcutType}
97      */
saveUserShortcutType(Context context, PreferredShortcut shortcut)98     public static void saveUserShortcutType(Context context, PreferredShortcut shortcut) {
99         final String componentName = shortcut.getComponentName();
100         if (componentName == null) {
101             return;
102         }
103 
104         // Create a mutable set to modify
105         final Set<String> info = new HashSet<>(getFromSharedPreferences(context));
106         info.removeIf(str -> str.contains(componentName));
107         info.add(shortcut.toString());
108         saveToSharedPreferences(context, info);
109     }
110 
111     /**
112      * Update the user preferred shortcut from Settings data
113      *
114      * @param context    {@link Context} to access the {@link SharedPreferences}
115      * @param components contains a set of {@link ComponentName} the service or activity. The
116      *                   string
117      *                   representation of the ComponentName should be in the format of
118      *                   {@link ComponentName#flattenToString()}.
119      */
updatePreferredShortcutsFromSettings( @onNull Context context, @NonNull Set<String> components)120     public static void updatePreferredShortcutsFromSettings(
121             @NonNull Context context, @NonNull Set<String> components) {
122         final Map<Integer, Set<String>> shortcutTypeToTargets = new ArrayMap<>();
123         for (int shortcutType : AccessibilityUtil.SHORTCUTS_ORDER_IN_UI) {
124             shortcutTypeToTargets.put(
125                     shortcutType,
126                     ShortcutUtils.getShortcutTargetsFromSettings(
127                             context, shortcutType, UserHandle.myUserId()));
128         }
129 
130         for (String target : components) {
131             int shortcutTypes = DEFAULT;
132             for (Map.Entry<Integer, Set<String>> entry : shortcutTypeToTargets.entrySet()) {
133                 if (entry.getValue().contains(target)) {
134                     shortcutTypes |= entry.getKey();
135                 }
136             }
137 
138             if (shortcutTypes != DEFAULT) {
139                 final PreferredShortcut shortcut = new PreferredShortcut(
140                         target, shortcutTypes);
141                 PreferredShortcuts.saveUserShortcutType(context, shortcut);
142             }
143         }
144     }
145 
146     /**
147      * Returns a immutable set of {@link PreferredShortcut#toString()} list from
148      * SharedPreferences.
149      */
getFromSharedPreferences(Context context)150     private static Set<String> getFromSharedPreferences(Context context) {
151         return getSharedPreferences(context).getStringSet(USER_SHORTCUT_TYPE, Set.of());
152     }
153 
154     /** Sets a set of {@link PreferredShortcut#toString()} list into SharedPreferences. */
saveToSharedPreferences(Context context, Set<String> data)155     private static void saveToSharedPreferences(Context context, Set<String> data) {
156         SharedPreferences.Editor editor = getSharedPreferences(context).edit();
157         editor.putStringSet(USER_SHORTCUT_TYPE, data).apply();
158     }
159 
getSharedPreferences(Context context)160     private static SharedPreferences getSharedPreferences(Context context) {
161         return context.getSharedPreferences(ACCESSIBILITY_PERF, Context.MODE_PRIVATE);
162     }
163 
164     @VisibleForTesting(otherwise = VisibleForTesting.NONE)
clearPreferredShortcuts(Context context)165     static void clearPreferredShortcuts(Context context) {
166         getSharedPreferences(context).edit().clear().apply();
167     }
168 
PreferredShortcuts()169     private PreferredShortcuts() {}
170 }
171