Unified service and shortcut state summary on a11y settings page.

Bug: 210026562
Test: manual
Test: atest

Change-Id: I4d5ff6b10d6bfd2fe6b3de1849d00a9d084bf269
This commit is contained in:
Chun-Ku Lin
2023-05-15 18:12:55 +00:00
parent 53c0788cc9
commit b8084ecfcd
25 changed files with 839 additions and 189 deletions

View File

@@ -246,34 +246,74 @@ public class AccessibilitySettings extends DashboardFragment {
* @return The service summary
*/
public static CharSequence getServiceSummary(Context context, AccessibilityServiceInfo info,
boolean serviceEnabled) {
boolean serviceEnabled) {
if (serviceEnabled && info.crashed) {
return context.getText(R.string.accessibility_summary_state_stopped);
}
final CharSequence serviceState;
final int fragmentType = AccessibilityUtil.getAccessibilityServiceFragmentType(info);
if (fragmentType == AccessibilityServiceFragmentType.INVISIBLE_TOGGLE) {
final ComponentName componentName = new ComponentName(
info.getResolveInfo().serviceInfo.packageName,
info.getResolveInfo().serviceInfo.name);
final boolean shortcutEnabled = AccessibilityUtil.getUserShortcutTypesFromSettings(
context, componentName) != AccessibilityUtil.UserShortcutType.EMPTY;
serviceState = shortcutEnabled
? context.getText(R.string.accessibility_summary_shortcut_enabled)
: context.getText(R.string.accessibility_summary_shortcut_disabled);
} else {
serviceState = serviceEnabled
? context.getText(R.string.accessibility_summary_state_enabled)
: context.getText(R.string.accessibility_summary_state_disabled);
}
final ComponentName componentName = new ComponentName(
info.getResolveInfo().serviceInfo.packageName,
info.getResolveInfo().serviceInfo.name);
final boolean shortcutEnabled = AccessibilityUtil.getUserShortcutTypesFromSettings(
context, componentName) != AccessibilityUtil.UserShortcutType.EMPTY;
// Example shortcutState: "Shortcut on"
CharSequence shortcutState = shortcutEnabled
? context.getText(R.string.accessibility_summary_shortcut_enabled)
: context.getText(R.string.generic_accessibility_feature_shortcut_off);
// Example serviceSummary: "Control device via large menu"
final CharSequence serviceSummary = info.loadSummary(context.getPackageManager());
final String stateSummaryCombo = context.getString(
R.string.preference_summary_default_combination,
serviceState, serviceSummary);
return TextUtils.isEmpty(serviceSummary) ? serviceState : stateSummaryCombo;
if (fragmentType == AccessibilityServiceFragmentType.INVISIBLE_TOGGLE) {
// Example result: "Shortcut on / Control device via large menu"
return TextUtils.isEmpty(serviceSummary)
? shortcutState
: context.getString(
R.string.preference_summary_default_combination, shortcutState,
serviceSummary);
} else {
// Example serviceState: "Service on"
CharSequence serviceState = serviceEnabled
? context.getText(R.string.generic_accessibility_service_on)
: context.getText(R.string.generic_accessibility_service_off);
// Example result: "Service on / Shortcut on / Speak items on screen"
return TextUtils.isEmpty(serviceSummary)
? context.getString(
R.string.preference_summary_default_combination,
serviceState, shortcutState)
: context.getString(
R.string.accessibility_feature_full_state_summary, serviceState,
shortcutState, serviceSummary);
}
}
/**
* Returns the summary for the current shortcut state of the accessibility app
* captured in the {@link AccessibilityShortcutInfo}
*/
public static CharSequence getA11yShortcutInfoPreferenceSummary(
Context context, AccessibilityShortcutInfo info) {
boolean shortcutEnabled = AccessibilityUtil.getUserShortcutTypesFromSettings(
context, info.getComponentName()) != AccessibilityUtil.UserShortcutType.EMPTY;
// Example shortcutState: "Shortcut on"
CharSequence shortcutState = shortcutEnabled
? context.getText(R.string.accessibility_summary_shortcut_enabled)
: context.getText(R.string.generic_accessibility_feature_shortcut_off);
// Example serviceSummary: "Convert speech to text"
CharSequence serviceSummary = info.loadSummary(context.getPackageManager());
// Example result: "Shortcut on / Convert speech to text"
return TextUtils.isEmpty(serviceSummary)
? shortcutState
: context.getString(
R.string.preference_summary_default_combination,
shortcutState, serviceSummary);
}
/**

View File

@@ -434,7 +434,7 @@ public abstract class AccessibilityShortcutPreferenceFragment extends Restricted
}
if (!mShortcutPreference.isChecked()) {
return context.getText(R.string.switch_off_text);
return context.getText(R.string.accessibility_shortcut_state_off);
}
final int shortcutTypes = PreferredShortcuts.retrieveUserShortcutType(context,

View File

@@ -37,6 +37,7 @@ import android.view.accessibility.AccessibilityManager;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import androidx.annotation.VisibleForTesting;
import com.android.settings.R;
@@ -124,15 +125,15 @@ public final class AccessibilityUtil {
}
/**
* Return On/Off string according to the setting which specifies the integer value 1 or 0. This
* Returns On/Off string according to the setting which specifies the integer value 1 or 0. This
* setting is defined in the secure system settings {@link android.provider.Settings.Secure}.
*/
static CharSequence getSummary(Context context, String settingsSecureKey) {
final boolean enabled = Settings.Secure.getInt(context.getContentResolver(),
static CharSequence getSummary(
Context context, String settingsSecureKey, @StringRes int enabledString,
@StringRes int disabledString) {
boolean enabled = Settings.Secure.getInt(context.getContentResolver(),
settingsSecureKey, State.OFF) == State.ON;
final int resId = enabled ? R.string.accessibility_feature_state_on
: R.string.accessibility_feature_state_off;
return context.getResources().getText(resId);
return context.getResources().getText(enabled ? enabledString : disabledString);
}
/**
@@ -289,6 +290,41 @@ public final class AccessibilityUtil {
Settings.Secure.putString(context.getContentResolver(), targetKey, joiner.toString());
}
/**
* Returns the full status with a feature summary.
* For example, "$(feature on) / Shortcut on / Speak items on screen".
*
* @param context The current context.
* @param componentName The component name in Settings to query
* if the shortcut turned on.
* @param settingsSecureKey One of the key defined in
* {@link Settings.Secure}.
* @param featureOnTextId The string resource id representing the feature is turned on.
* @param featureOffTextId The string resource id representing the feature is turned off.
* @param featureSummaryId The string resource id of the feature summary.
*/
static CharSequence getFeatureFullStateSummary(
Context context, @NonNull ComponentName componentName,
String settingsSecureKey,
@StringRes int featureOnTextId, @StringRes int featureOffTextId,
@StringRes int featureSummaryId) {
boolean shortcutEnabled = getUserShortcutTypesFromSettings(context, componentName)
!= AccessibilityUtil.UserShortcutType.EMPTY;
boolean featureEnabled = Settings.Secure.getInt(context.getContentResolver(),
settingsSecureKey, AccessibilityUtil.State.OFF) == AccessibilityUtil.State.ON;
return context.getString(
R.string.accessibility_feature_full_state_summary,
featureEnabled
? context.getString(featureOnTextId)
: context.getString(featureOffTextId),
shortcutEnabled
? context.getString(R.string.accessibility_summary_shortcut_enabled)
: context.getString(R.string.generic_accessibility_feature_shortcut_off),
context.getString(featureSummaryId)
);
}
/**
* Returns if component name existed in one of {@code shortcutTypes} string in Settings.
*

View File

@@ -53,7 +53,7 @@ public class AutoclickPreferenceController extends BasePreferenceController {
final boolean enabled = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED, OFF) == ON;
if (!enabled) {
return mContext.getResources().getText(R.string.accessibility_feature_state_off);
return mContext.getResources().getText(R.string.autoclick_disabled);
}
final int delayMillis = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_AUTOCLICK_DELAY,

View File

@@ -19,6 +19,7 @@ package com.android.settings.accessibility;
import android.content.Context;
import android.provider.Settings;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
public class CaptioningPreferenceController extends BasePreferenceController {
@@ -35,6 +36,8 @@ public class CaptioningPreferenceController extends BasePreferenceController {
@Override
public CharSequence getSummary() {
return AccessibilityUtil.getSummary(mContext,
Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED);
Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED,
R.string.show_captions_enabled,
R.string.show_captions_disabled);
}
}

View File

@@ -68,6 +68,8 @@ public class ColorAndMotionFragment extends DashboardFragment {
mShortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED);
mShortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED);
mShortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE);
mShortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS);
mSettingsContentObserver = new AccessibilitySettingsContentObserver(new Handler());
mSettingsContentObserver.registerKeysToObserverCallback(mShortcutFeatureKeys,
@@ -123,8 +125,6 @@ public class ColorAndMotionFragment extends DashboardFragment {
final PreferenceCategory experimentalCategory = getPreferenceScreen().findPreference(
CATEGORY_EXPERIMENTAL);
if (ColorDisplayManager.isColorTransformAccelerated(getContext())) {
mDisplayDaltonizerPreferenceScreen.setSummary(AccessibilityUtil.getSummary(
getContext(), Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED));
getPreferenceScreen().removePreference(experimentalCategory);
} else {
// Move following preferences to experimental category if device don't supports HWC

View File

@@ -16,9 +16,12 @@
package com.android.settings.accessibility;
import static com.android.internal.accessibility.AccessibilityShortcutController.COLOR_INVERSION_COMPONENT_NAME;
import android.content.Context;
import android.provider.Settings;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
/** Controller that shows the color inversion summary. */
@@ -33,7 +36,11 @@ public class ColorInversionPreferenceController extends BasePreferenceController
@Override
public CharSequence getSummary() {
return AccessibilityUtil.getSummary(mContext, DISPLAY_INVERSION_ENABLED);
return AccessibilityUtil.getFeatureFullStateSummary(
mContext, COLOR_INVERSION_COMPONENT_NAME,
DISPLAY_INVERSION_ENABLED,
R.string.color_inversion_state_on, R.string.color_inversion_state_off,
R.string.color_inversion_feature_summary);
}
@Override

View File

@@ -16,9 +16,12 @@
package com.android.settings.accessibility;
import static com.android.internal.accessibility.AccessibilityShortcutController.DALTONIZER_COMPONENT_NAME;
import android.content.Context;
import android.provider.Settings;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
/** Controller that shows and updates the color correction summary. */
@@ -37,6 +40,10 @@ public class DaltonizerPreferenceController extends BasePreferenceController {
@Override
public CharSequence getSummary() {
return AccessibilityUtil.getSummary(mContext, DALTONIZER_ENABLED);
return AccessibilityUtil.getFeatureFullStateSummary(
mContext, DALTONIZER_COMPONENT_NAME,
DALTONIZER_ENABLED,
R.string.daltonizer_state_on, R.string.daltonizer_state_off,
R.string.daltonizer_feature_summary);
}
}

View File

@@ -20,10 +20,12 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.provider.Settings;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import java.util.List;
@@ -54,5 +56,16 @@ public class LiveCaptionPreferenceController extends BasePreferenceController {
public void updateState(Preference preference) {
super.updateState(preference);
preference.setIntent(LIVE_CAPTION_INTENT);
boolean enabled = Settings.Secure.getInt(
mContext.getContentResolver(),
Settings.Secure.ODI_CAPTIONS_ENABLED, AccessibilityUtil.State.OFF)
== AccessibilityUtil.State.ON;
CharSequence serviceState = mContext.getText(enabled
? R.string.live_caption_enabled : R.string.live_caption_disabled);
preference.setSummary(
mContext.getString(
R.string.preference_summary_default_combination,
serviceState, mContext.getText(R.string.live_caption_summary)));
}
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright (C) 2023 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.content.Context;
import com.android.settings.R;
import com.android.settings.gestures.OneHandedEnablePreferenceController;
import com.android.settings.gestures.OneHandedSettingsUtils;
/**
* OneHandedPreferenceController is the same as {@link OneHandedEnablePreferenceController} excepts
* that the summary shown on the preference item would include the short description of One-handed
* mode, so that the UI representation is consistent with other items on Accessibility Settings
*/
public final class OneHandedPreferenceController extends OneHandedEnablePreferenceController {
public OneHandedPreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
}
@Override
public CharSequence getSummary() {
return mContext.getString(
R.string.preference_summary_default_combination,
mContext.getText(OneHandedSettingsUtils.isOneHandedModeEnabled(mContext)
? R.string.gesture_setting_on : R.string.gesture_setting_off),
mContext.getText(R.string.one_handed_mode_intro_text));
}
}

View File

@@ -159,7 +159,8 @@ public class RestrictedPreferenceHelper {
final String key = componentName.flattenToString();
final CharSequence title = activityInfo.loadLabel(mPm);
final String summary = info.loadSummary(mPm);
final CharSequence summary =
AccessibilitySettings.getA11yShortcutInfoPreferenceSummary(mContext, info);
final String fragment =
LaunchAccessibilityActivityPreferenceFragment.class.getName();

View File

@@ -662,7 +662,7 @@ public abstract class ToggleFeaturePreferenceFragment extends DashboardFragment
}
if (!mShortcutPreference.isChecked()) {
return context.getText(R.string.switch_off_text);
return context.getText(R.string.accessibility_shortcut_state_off);
}
final int shortcutTypes = PreferredShortcuts.retrieveUserShortcutType(context,

View File

@@ -751,9 +751,12 @@ public class ToggleScreenMagnificationPreferenceFragment extends
*/
public static CharSequence getServiceSummary(Context context) {
// Get the user shortcut type from settings provider.
final int uerShortcutType = getUserShortcutTypeFromSettings(context);
return (uerShortcutType != AccessibilityUtil.UserShortcutType.EMPTY)
? context.getText(R.string.accessibility_summary_shortcut_enabled)
: context.getText(R.string.accessibility_summary_shortcut_disabled);
int shortcutType = getUserShortcutTypeFromSettings(context);
return context.getString(
R.string.preference_summary_default_combination,
shortcutType != AccessibilityUtil.UserShortcutType.EMPTY
? context.getString(R.string.accessibility_summary_shortcut_enabled)
: context.getString(R.string.generic_accessibility_feature_shortcut_off),
context.getText(R.string.magnification_feature_summary));
}
}