diff --git a/src/com/android/settings/accessibility/AccessibilityActivityPreference.java b/src/com/android/settings/accessibility/AccessibilityActivityPreference.java new file mode 100644 index 00000000000..da4598e6d48 --- /dev/null +++ b/src/com/android/settings/accessibility/AccessibilityActivityPreference.java @@ -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); + } +} diff --git a/src/com/android/settings/accessibility/AccessibilityServicePreference.java b/src/com/android/settings/accessibility/AccessibilityServicePreference.java new file mode 100644 index 00000000000..c2c1a22be9c --- /dev/null +++ b/src/com/android/settings/accessibility/AccessibilityServicePreference.java @@ -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); + } +} diff --git a/src/com/android/settings/accessibility/RestrictedPreferenceHelper.java b/src/com/android/settings/accessibility/RestrictedPreferenceHelper.java index 7455eea51ce..34646ba7fcb 100644 --- a/src/com/android/settings/accessibility/RestrictedPreferenceHelper.java +++ b/src/com/android/settings/accessibility/RestrictedPreferenceHelper.java @@ -17,7 +17,6 @@ package com.android.settings.accessibility; 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.AccessibilityShortcutInfo; @@ -26,20 +25,13 @@ import android.app.admin.DevicePolicyManager; import android.content.ComponentName; import android.content.Context; import android.content.pm.ActivityInfo; -import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; -import android.graphics.Color; -import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.UserHandle; import android.text.TextUtils; -import androidx.core.content.ContextCompat; - import com.android.settings.R; -import com.android.settings.Utils; import com.android.settings.development.Enable16kUtils; -import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedLockUtilsInternal; import com.android.settingslib.RestrictedPreference; @@ -58,13 +50,11 @@ public class RestrictedPreferenceHelper { private final Context mContext; private final DevicePolicyManager mDpm; - private final PackageManager mPm; private final AppOpsManager mAppOps; public RestrictedPreferenceHelper(Context context) { mContext = context; mDpm = context.getSystemService(DevicePolicyManager.class); - mPm = context.getPackageManager(); mAppOps = context.getSystemService(AppOpsManager.class); } @@ -96,46 +86,15 @@ public class RestrictedPreferenceHelper { && Enable16kUtils.isPageAgnosticModeOn(mContext)) { continue; } + final ComponentName componentName = new ComponentName(packageName, resolveInfo.serviceInfo.name); - - final String key = componentName.flattenToString(); - final CharSequence title = resolveInfo.loadLabel(mPm); 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); - - 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); } return preferenceList; @@ -164,47 +123,17 @@ public class RestrictedPreferenceHelper { final ActivityInfo activityInfo = info.getActivityInfo(); 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); - + RestrictedPreference preference = new AccessibilityActivityPreference( + mContext, componentName.getPackageName(), activityInfo.applicationInfo.uid, + info); 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); } return preferenceList; } - private String getAccessibilityServiceFragmentTypeName(AccessibilityServiceInfo info) { + static String getAccessibilityServiceFragmentTypeName(AccessibilityServiceInfo info) { final int type = AccessibilityUtil.getAccessibilityServiceFragmentType(info); switch (type) { 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, final List permittedServices, boolean serviceEnabled) { // permittedServices null means all accessibility services are allowed. @@ -304,7 +216,7 @@ public class RestrictedPreferenceHelper { } /** 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, String htmlDescription, ComponentName componentName, int metricsCategory) { final Bundle extras = preference.getExtras(); @@ -327,7 +239,7 @@ public class RestrictedPreferenceHelper { * @param resolveInfo The service resolve info. * @param serviceEnabled Whether the accessibility service is enabled. */ - private void putServiceExtras(RestrictedPreference preference, ResolveInfo resolveInfo, + static void putServiceExtras(RestrictedPreference preference, ResolveInfo resolveInfo, Boolean serviceEnabled) { 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 * the settings for this accessibility feature. */ - private void putSettingsExtras(RestrictedPreference preference, String packageName, + static void putSettingsExtras(RestrictedPreference preference, String packageName, String settingsClassName) { final Bundle extras = preference.getExtras(); if (!TextUtils.isEmpty(settingsClassName)) { 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, new ComponentName(packageName, settingsClassName).flattenToString()); } @@ -370,7 +283,7 @@ public class RestrictedPreferenceHelper { * @param tileServiceClassName The component name of tileService is associated with this * accessibility feature. */ - private void putTileServiceExtras(RestrictedPreference preference, String packageName, + static void putTileServiceExtras(RestrictedPreference preference, String packageName, String tileServiceClassName) { final Bundle extras = preference.getExtras(); if (!TextUtils.isEmpty(tileServiceClassName)) {