[Refactor] Create a dedicated AccessibilityServicePreference and

AccessibilityActivityPreference to encapture the method for loading the
content for AccessibilityService and AccessibilityShortcutInfo

Bug: 327052480
Test: atest com.android.settings.accessibility
Flag: EXEMPT mechanical refactor

Change-Id: I698a1d366e8ab82c8efdcae293a1ba1771925121
This commit is contained in:
Chun-Ku Lin
2024-06-01 03:01:29 +00:00
parent 59417f3737
commit ba408fbb06
3 changed files with 226 additions and 101 deletions

View File

@@ -0,0 +1,103 @@
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.accessibility;
import android.accessibilityservice.AccessibilityShortcutInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import androidx.core.content.ContextCompat;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.RestrictedPreference;
/**
* Preference item for showing an accessibility activity in a preference list
*/
public class AccessibilityActivityPreference extends RestrictedPreference {
// Index of the first preference in a preference category.
private static final int FIRST_PREFERENCE_IN_CATEGORY_INDEX = -1;
private static final String TARGET_FRAGMENT =
LaunchAccessibilityActivityPreferenceFragment.class.getName();
private final AccessibilityShortcutInfo mA11yShortcutInfo;
private final PackageManager mPm;
private final ComponentName mComponentName;
public AccessibilityActivityPreference(Context context, String packageName, int uid,
AccessibilityShortcutInfo a11yShortcutInfo) {
super(context, packageName, uid);
mPm = context.getPackageManager();
mA11yShortcutInfo = a11yShortcutInfo;
mComponentName = a11yShortcutInfo.getComponentName();
// setup basic info for a preference
setKey(mComponentName.flattenToString());
setTitle(a11yShortcutInfo.getActivityInfo().loadLabel(mPm));
setSummary(a11yShortcutInfo.loadSummary(mPm));
setFragment(TARGET_FRAGMENT);
setIconSize(ICON_SIZE_MEDIUM);
setIconSpaceReserved(true);
setPersistent(false); // Disable SharedPreferences.
setOrder(FIRST_PREFERENCE_IN_CATEGORY_INDEX);
final Drawable icon = getA11yActivityIcon();
setIcon(icon);
final Bundle extras = getExtras();
extras.putParcelable(AccessibilitySettings.EXTRA_COMPONENT_NAME, mComponentName);
setupDataForOpenFragment();
}
private Drawable getA11yActivityIcon() {
ActivityInfo activityInfo = mA11yShortcutInfo.getActivityInfo();
Drawable serviceIcon;
if (activityInfo.getIconResource() == 0) {
serviceIcon = ContextCompat.getDrawable(getContext(),
R.drawable.ic_accessibility_generic);
} else {
serviceIcon = activityInfo.loadIcon(mPm);
}
return Utils.getAdaptiveIcon(getContext(), serviceIcon, Color.WHITE);
}
private void setupDataForOpenFragment() {
final String prefKey = getKey();
final int imageRes = mA11yShortcutInfo.getAnimatedImageRes();
final CharSequence intro = mA11yShortcutInfo.loadIntro(mPm);
final CharSequence description = mA11yShortcutInfo.loadDescription(mPm);
final String htmlDescription = mA11yShortcutInfo.loadHtmlDescription(mPm);
final String settingsClassName = mA11yShortcutInfo.getSettingsActivityName();
final String tileServiceClassName = mA11yShortcutInfo.getTileServiceName();
final int metricsCategory = FeatureFactory.getFeatureFactory()
.getAccessibilityMetricsFeatureProvider()
.getDownloadedFeatureMetricsCategory(mComponentName);
RestrictedPreferenceHelper.putBasicExtras(
this, prefKey, getTitle(), intro, description, imageRes,
htmlDescription, mComponentName, metricsCategory);
RestrictedPreferenceHelper.putSettingsExtras(this, getPackageName(), settingsClassName);
RestrictedPreferenceHelper.putTileServiceExtras(
this, getPackageName(), tileServiceClassName);
}
}

View File

@@ -0,0 +1,109 @@
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.accessibility;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import androidx.core.content.ContextCompat;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.RestrictedPreference;
/**
* Preference item for showing an accessibility service in a preference list
*/
public class AccessibilityServicePreference extends RestrictedPreference {
// Index of the first preference in a preference category.
private static final int FIRST_PREFERENCE_IN_CATEGORY_INDEX = -1;
private final PackageManager mPm;
private final AccessibilityServiceInfo mA11yServiceInfo;
private final ComponentName mComponentName;
private final boolean mServiceEnabled;
public AccessibilityServicePreference(Context context, String packageName, int uid,
AccessibilityServiceInfo a11yServiceInfo, boolean serviceEnabled) {
super(context, packageName, uid);
mPm = context.getPackageManager();
mA11yServiceInfo = a11yServiceInfo;
mServiceEnabled = serviceEnabled;
mComponentName = new ComponentName(packageName,
mA11yServiceInfo.getResolveInfo().serviceInfo.name);
// setup basic info for a preference
setKey(mComponentName.flattenToString());
setTitle(mA11yServiceInfo.getResolveInfo().loadLabel(mPm));
setSummary(AccessibilitySettings.getServiceSummary(
getContext(), mA11yServiceInfo, mServiceEnabled));
setFragment(RestrictedPreferenceHelper.getAccessibilityServiceFragmentTypeName(
mA11yServiceInfo));
setIconSize(ICON_SIZE_MEDIUM);
setIconSpaceReserved(true);
setPersistent(false); // Disable SharedPreferences.
setOrder(FIRST_PREFERENCE_IN_CATEGORY_INDEX);
final Drawable icon = getA11yServiceIcon();
setIcon(icon);
final Bundle extras = getExtras();
extras.putParcelable(AccessibilitySettings.EXTRA_COMPONENT_NAME, mComponentName);
setupDataForOpenFragment();
}
private Drawable getA11yServiceIcon() {
ResolveInfo resolveInfo = mA11yServiceInfo.getResolveInfo();
Drawable serviceIcon;
if (resolveInfo.getIconResource() == 0) {
serviceIcon = ContextCompat.getDrawable(getContext(),
R.drawable.ic_accessibility_generic);
} else {
serviceIcon = resolveInfo.loadIcon(mPm);
}
return Utils.getAdaptiveIcon(getContext(), serviceIcon, Color.WHITE);
}
private void setupDataForOpenFragment() {
final String prefKey = getKey();
final int imageRes = mA11yServiceInfo.getAnimatedImageRes();
final CharSequence intro = mA11yServiceInfo.loadIntro(mPm);
final CharSequence description = AccessibilitySettings.getServiceDescription(
getContext(), mA11yServiceInfo, mServiceEnabled);
final String htmlDescription = mA11yServiceInfo.loadHtmlDescription(mPm);
final String settingsClassName = mA11yServiceInfo.getSettingsActivityName();
final String tileServiceClassName = mA11yServiceInfo.getTileServiceName();
final ResolveInfo resolveInfo = mA11yServiceInfo.getResolveInfo();
final int metricsCategory = FeatureFactory.getFeatureFactory()
.getAccessibilityMetricsFeatureProvider()
.getDownloadedFeatureMetricsCategory(mComponentName);
RestrictedPreferenceHelper.putBasicExtras(
this, prefKey, getTitle(), intro, description, imageRes,
htmlDescription, mComponentName, metricsCategory);
RestrictedPreferenceHelper.putServiceExtras(this, resolveInfo, mServiceEnabled);
RestrictedPreferenceHelper.putSettingsExtras(this, getPackageName(), settingsClassName);
RestrictedPreferenceHelper.putTileServiceExtras(
this, getPackageName(), tileServiceClassName);
}
}

View File

@@ -17,7 +17,6 @@
package com.android.settings.accessibility; package com.android.settings.accessibility;
import static com.android.settings.accessibility.AccessibilitySettings.VOICE_ACCESS_SERVICE; import static com.android.settings.accessibility.AccessibilitySettings.VOICE_ACCESS_SERVICE;
import static com.android.settingslib.widget.TwoTargetPreference.ICON_SIZE_MEDIUM;
import android.accessibilityservice.AccessibilityServiceInfo; import android.accessibilityservice.AccessibilityServiceInfo;
import android.accessibilityservice.AccessibilityShortcutInfo; import android.accessibilityservice.AccessibilityShortcutInfo;
@@ -26,20 +25,13 @@ import android.app.admin.DevicePolicyManager;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo; import android.content.pm.ResolveInfo;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle; import android.os.Bundle;
import android.os.UserHandle; import android.os.UserHandle;
import android.text.TextUtils; import android.text.TextUtils;
import androidx.core.content.ContextCompat;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.development.Enable16kUtils; import com.android.settings.development.Enable16kUtils;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtilsInternal; import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedPreference; import com.android.settingslib.RestrictedPreference;
@@ -58,13 +50,11 @@ public class RestrictedPreferenceHelper {
private final Context mContext; private final Context mContext;
private final DevicePolicyManager mDpm; private final DevicePolicyManager mDpm;
private final PackageManager mPm;
private final AppOpsManager mAppOps; private final AppOpsManager mAppOps;
public RestrictedPreferenceHelper(Context context) { public RestrictedPreferenceHelper(Context context) {
mContext = context; mContext = context;
mDpm = context.getSystemService(DevicePolicyManager.class); mDpm = context.getSystemService(DevicePolicyManager.class);
mPm = context.getPackageManager();
mAppOps = context.getSystemService(AppOpsManager.class); mAppOps = context.getSystemService(AppOpsManager.class);
} }
@@ -96,46 +86,15 @@ public class RestrictedPreferenceHelper {
&& Enable16kUtils.isPageAgnosticModeOn(mContext)) { && Enable16kUtils.isPageAgnosticModeOn(mContext)) {
continue; continue;
} }
final ComponentName componentName = new ComponentName(packageName, final ComponentName componentName = new ComponentName(packageName,
resolveInfo.serviceInfo.name); resolveInfo.serviceInfo.name);
final String key = componentName.flattenToString();
final CharSequence title = resolveInfo.loadLabel(mPm);
final boolean serviceEnabled = enabledServices.contains(componentName); final boolean serviceEnabled = enabledServices.contains(componentName);
final CharSequence summary = AccessibilitySettings.getServiceSummary(
mContext, info, serviceEnabled);
final String fragment = getAccessibilityServiceFragmentTypeName(info);
Drawable icon = resolveInfo.loadIcon(mPm);
if (resolveInfo.getIconResource() == 0) {
icon = ContextCompat.getDrawable(mContext,
R.drawable.ic_accessibility_generic);
}
final RestrictedPreference preference = createRestrictedPreference(key, title,
summary, icon, fragment, packageName,
resolveInfo.serviceInfo.applicationInfo.uid);
RestrictedPreference preference = new AccessibilityServicePreference(
mContext, packageName, resolveInfo.serviceInfo.applicationInfo.uid,
info, serviceEnabled);
setRestrictedPreferenceEnabled(preference, permittedServices, serviceEnabled); setRestrictedPreferenceEnabled(preference, permittedServices, serviceEnabled);
final String prefKey = preference.getKey();
final int imageRes = info.getAnimatedImageRes();
final CharSequence intro = info.loadIntro(mPm);
final CharSequence description = AccessibilitySettings.getServiceDescription(
mContext, info, serviceEnabled);
final String htmlDescription = info.loadHtmlDescription(mPm);
final String settingsClassName = info.getSettingsActivityName();
final String tileServiceClassName = info.getTileServiceName();
final int metricsCategory = FeatureFactory.getFeatureFactory()
.getAccessibilityMetricsFeatureProvider()
.getDownloadedFeatureMetricsCategory(componentName);
putBasicExtras(preference, prefKey, title, intro, description, imageRes,
htmlDescription, componentName, metricsCategory);
putServiceExtras(preference, resolveInfo, serviceEnabled);
putSettingsExtras(preference, packageName, settingsClassName);
putTileServiceExtras(preference, packageName, tileServiceClassName);
preferenceList.add(preference); preferenceList.add(preference);
} }
return preferenceList; return preferenceList;
@@ -164,47 +123,17 @@ public class RestrictedPreferenceHelper {
final ActivityInfo activityInfo = info.getActivityInfo(); final ActivityInfo activityInfo = info.getActivityInfo();
final ComponentName componentName = info.getComponentName(); final ComponentName componentName = info.getComponentName();
final String key = componentName.flattenToString();
final CharSequence title = activityInfo.loadLabel(mPm);
final String summary = info.loadSummary(mPm);
final String fragment =
LaunchAccessibilityActivityPreferenceFragment.class.getName();
Drawable icon = activityInfo.loadIcon(mPm);
if (activityInfo.getIconResource() == 0) {
icon = ContextCompat.getDrawable(mContext, R.drawable.ic_accessibility_generic);
}
final RestrictedPreference preference = createRestrictedPreference(key, title,
summary, icon, fragment, componentName.getPackageName(),
activityInfo.applicationInfo.uid);
final boolean serviceEnabled = enabledServices.contains(componentName); final boolean serviceEnabled = enabledServices.contains(componentName);
RestrictedPreference preference = new AccessibilityActivityPreference(
mContext, componentName.getPackageName(), activityInfo.applicationInfo.uid,
info);
setRestrictedPreferenceEnabled(preference, permittedServices, serviceEnabled); setRestrictedPreferenceEnabled(preference, permittedServices, serviceEnabled);
final String prefKey = preference.getKey();
final CharSequence intro = info.loadIntro(mPm);
final String description = info.loadDescription(mPm);
final int imageRes = info.getAnimatedImageRes();
final String htmlDescription = info.loadHtmlDescription(mPm);
final String settingsClassName = info.getSettingsActivityName();
final String tileServiceClassName = info.getTileServiceName();
final int metricsCategory = FeatureFactory.getFeatureFactory()
.getAccessibilityMetricsFeatureProvider()
.getDownloadedFeatureMetricsCategory(componentName);
putBasicExtras(preference, prefKey, title, intro, description, imageRes,
htmlDescription, componentName, metricsCategory);
putSettingsExtras(preference, componentName.getPackageName(), settingsClassName);
putTileServiceExtras(preference, componentName.getPackageName(),
tileServiceClassName);
preferenceList.add(preference); preferenceList.add(preference);
} }
return preferenceList; return preferenceList;
} }
private String getAccessibilityServiceFragmentTypeName(AccessibilityServiceInfo info) { static String getAccessibilityServiceFragmentTypeName(AccessibilityServiceInfo info) {
final int type = AccessibilityUtil.getAccessibilityServiceFragmentType(info); final int type = AccessibilityUtil.getAccessibilityServiceFragmentType(info);
switch (type) { switch (type) {
case AccessibilityUtil.AccessibilityServiceFragmentType.VOLUME_SHORTCUT_TOGGLE: case AccessibilityUtil.AccessibilityServiceFragmentType.VOLUME_SHORTCUT_TOGGLE:
@@ -219,23 +148,6 @@ public class RestrictedPreferenceHelper {
} }
} }
private RestrictedPreference createRestrictedPreference(String key, CharSequence title,
CharSequence summary, Drawable icon, String fragment, String packageName, int uid) {
final RestrictedPreference preference = new RestrictedPreference(mContext, packageName,
uid);
preference.setKey(key);
preference.setTitle(title);
preference.setSummary(summary);
preference.setIcon(Utils.getAdaptiveIcon(mContext, icon, Color.WHITE));
preference.setFragment(fragment);
preference.setIconSize(ICON_SIZE_MEDIUM);
preference.setPersistent(false); // Disable SharedPreferences.
preference.setOrder(FIRST_PREFERENCE_IN_CATEGORY_INDEX);
return preference;
}
private void setRestrictedPreferenceEnabled(RestrictedPreference preference, private void setRestrictedPreferenceEnabled(RestrictedPreference preference,
final List<String> permittedServices, boolean serviceEnabled) { final List<String> permittedServices, boolean serviceEnabled) {
// permittedServices null means all accessibility services are allowed. // permittedServices null means all accessibility services are allowed.
@@ -304,7 +216,7 @@ public class RestrictedPreferenceHelper {
} }
/** Puts the basic extras into {@link RestrictedPreference}'s getExtras(). */ /** Puts the basic extras into {@link RestrictedPreference}'s getExtras(). */
private void putBasicExtras(RestrictedPreference preference, String prefKey, static void putBasicExtras(RestrictedPreference preference, String prefKey,
CharSequence title, CharSequence intro, CharSequence summary, int imageRes, CharSequence title, CharSequence intro, CharSequence summary, int imageRes,
String htmlDescription, ComponentName componentName, int metricsCategory) { String htmlDescription, ComponentName componentName, int metricsCategory) {
final Bundle extras = preference.getExtras(); final Bundle extras = preference.getExtras();
@@ -327,7 +239,7 @@ public class RestrictedPreferenceHelper {
* @param resolveInfo The service resolve info. * @param resolveInfo The service resolve info.
* @param serviceEnabled Whether the accessibility service is enabled. * @param serviceEnabled Whether the accessibility service is enabled.
*/ */
private void putServiceExtras(RestrictedPreference preference, ResolveInfo resolveInfo, static void putServiceExtras(RestrictedPreference preference, ResolveInfo resolveInfo,
Boolean serviceEnabled) { Boolean serviceEnabled) {
final Bundle extras = preference.getExtras(); final Bundle extras = preference.getExtras();
@@ -345,13 +257,14 @@ public class RestrictedPreferenceHelper {
* @param settingsClassName The component name of an activity that allows the user to modify * @param settingsClassName The component name of an activity that allows the user to modify
* the settings for this accessibility feature. * the settings for this accessibility feature.
*/ */
private void putSettingsExtras(RestrictedPreference preference, String packageName, static void putSettingsExtras(RestrictedPreference preference, String packageName,
String settingsClassName) { String settingsClassName) {
final Bundle extras = preference.getExtras(); final Bundle extras = preference.getExtras();
if (!TextUtils.isEmpty(settingsClassName)) { if (!TextUtils.isEmpty(settingsClassName)) {
extras.putString(AccessibilitySettings.EXTRA_SETTINGS_TITLE, extras.putString(AccessibilitySettings.EXTRA_SETTINGS_TITLE,
mContext.getText(R.string.accessibility_menu_item_settings).toString()); preference.getContext().getText(
R.string.accessibility_menu_item_settings).toString());
extras.putString(AccessibilitySettings.EXTRA_SETTINGS_COMPONENT_NAME, extras.putString(AccessibilitySettings.EXTRA_SETTINGS_COMPONENT_NAME,
new ComponentName(packageName, settingsClassName).flattenToString()); new ComponentName(packageName, settingsClassName).flattenToString());
} }
@@ -370,7 +283,7 @@ public class RestrictedPreferenceHelper {
* @param tileServiceClassName The component name of tileService is associated with this * @param tileServiceClassName The component name of tileService is associated with this
* accessibility feature. * accessibility feature.
*/ */
private void putTileServiceExtras(RestrictedPreference preference, String packageName, static void putTileServiceExtras(RestrictedPreference preference, String packageName,
String tileServiceClassName) { String tileServiceClassName) {
final Bundle extras = preference.getExtras(); final Bundle extras = preference.getExtras();
if (!TextUtils.isEmpty(tileServiceClassName)) { if (!TextUtils.isEmpty(tileServiceClassName)) {