• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 android.accessibilityservice.AccessibilityShortcutInfo;
20 import android.content.ComponentName;
21 import android.content.Context;
22 import android.content.pm.ActivityInfo;
23 import android.content.pm.PackageManager;
24 import android.graphics.Color;
25 import android.graphics.drawable.Drawable;
26 import android.os.Bundle;
27 import android.util.Log;
28 
29 import androidx.annotation.NonNull;
30 import androidx.core.content.ContextCompat;
31 
32 import com.android.settings.R;
33 import com.android.settings.Utils;
34 import com.android.settings.overlay.FeatureFactory;
35 import com.android.settingslib.RestrictedPreference;
36 import com.android.settingslib.utils.ThreadUtils;
37 
38 import com.google.common.util.concurrent.ListenableFuture;
39 
40 import java.util.concurrent.ExecutionException;
41 
42 /**
43  * Preference item for showing an accessibility activity in a preference list
44  */
45 public class AccessibilityActivityPreference extends RestrictedPreference {
46     private static final String LOG_TAG = AccessibilityActivityPreference.class.getSimpleName();
47     // Index of the first preference in a preference category.
48     private static final int FIRST_PREFERENCE_IN_CATEGORY_INDEX = -1;
49     private static final String TARGET_FRAGMENT =
50             LaunchAccessibilityActivityPreferenceFragment.class.getName();
51     private final AccessibilityShortcutInfo mA11yShortcutInfo;
52     private final PackageManager mPm;
53     private final ComponentName mComponentName;
54     private final CharSequence mLabel;
55     private final ListenableFuture mExtraArgumentsFuture;
56 
AccessibilityActivityPreference(Context context, String packageName, int uid, AccessibilityShortcutInfo a11yShortcutInfo)57     public AccessibilityActivityPreference(Context context, String packageName, int uid,
58             AccessibilityShortcutInfo a11yShortcutInfo) {
59         super(context, packageName, uid);
60         mPm = context.getPackageManager();
61         mA11yShortcutInfo = a11yShortcutInfo;
62         mComponentName = a11yShortcutInfo.getComponentName();
63         mLabel = a11yShortcutInfo.getActivityInfo().loadLabel(mPm);
64         // setup basic info for a preference
65         setKey(mComponentName.flattenToString());
66         setTitle(mLabel);
67         setSummary(a11yShortcutInfo.loadSummary(mPm));
68         setFragment(TARGET_FRAGMENT);
69         setIconSize(ICON_SIZE_MEDIUM);
70         setIconSpaceReserved(true);
71         setPersistent(false); // Disable SharedPreferences.
72         setOrder(FIRST_PREFERENCE_IN_CATEGORY_INDEX);
73 
74         // kick off image loading tasks
75         ThreadUtils.postOnBackgroundThread(() -> {
76             final Drawable icon = getA11yActivityIcon();
77             ThreadUtils.getUiThreadHandler().post(() -> this.setIcon(icon));
78         });
79 
80         final Bundle extras = getExtras();
81         extras.putParcelable(AccessibilitySettings.EXTRA_COMPONENT_NAME, mComponentName);
82 
83         mExtraArgumentsFuture = ThreadUtils.postOnBackgroundThread(this::setupDataForOpenFragment);
84     }
85 
86     @Override
performClick()87     public void performClick() {
88         try {
89             mExtraArgumentsFuture.get();
90         } catch (InterruptedException | ExecutionException e) {
91             Log.e(LOG_TAG,
92                     "Unable to finish grabbing necessary arguments to open the fragment: "
93                             + "componentName: " + mComponentName);
94         }
95         super.performClick();
96     }
97 
98     /**
99      * Returns the label of the Accessibility Activity
100      */
getLabel()101     public CharSequence getLabel() {
102         return mLabel;
103     }
104 
105     @NonNull
getComponentName()106     public ComponentName getComponentName() {
107         return mComponentName;
108     }
109 
getA11yActivityIcon()110     private Drawable getA11yActivityIcon() {
111         ActivityInfo activityInfo = mA11yShortcutInfo.getActivityInfo();
112         Drawable serviceIcon;
113         if (activityInfo.getIconResource() == 0) {
114             serviceIcon = ContextCompat.getDrawable(getContext(),
115                     R.drawable.ic_accessibility_generic);
116         } else {
117             serviceIcon = activityInfo.loadIcon(mPm);
118         }
119         return Utils.getAdaptiveIcon(getContext(), serviceIcon, Color.WHITE);
120     }
121 
setupDataForOpenFragment()122     private void setupDataForOpenFragment() {
123         final String prefKey = getKey();
124         final int imageRes = mA11yShortcutInfo.getAnimatedImageRes();
125         final CharSequence intro = mA11yShortcutInfo.loadIntro(mPm);
126         final CharSequence description = mA11yShortcutInfo.loadDescription(mPm);
127         final String htmlDescription = mA11yShortcutInfo.loadHtmlDescription(mPm);
128         final String settingsClassName = mA11yShortcutInfo.getSettingsActivityName();
129         final String tileServiceClassName = mA11yShortcutInfo.getTileServiceName();
130         final int pageIdCategory = FeatureFactory.getFeatureFactory()
131                 .getAccessibilityPageIdFeatureProvider().getCategory(mComponentName);
132 
133         ThreadUtils.getUiThreadHandler().post(() -> {
134             RestrictedPreferenceHelper.putBasicExtras(
135                     this, prefKey, getTitle(), intro, description, imageRes,
136                     htmlDescription, mComponentName, pageIdCategory);
137             RestrictedPreferenceHelper.putSettingsExtras(this, getPackageName(), settingsClassName);
138             RestrictedPreferenceHelper.putTileServiceExtras(
139                     this, getPackageName(), tileServiceClassName);
140         });
141     }
142 }
143