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

@@ -727,4 +727,9 @@
<!-- Accessibility summary text for auto rotate [CHAR LIMIT=NONE] -->
<string name="auto_rotate_summary_a11y" product="tabled">When you move your tablet between portrait and landscape</string>
<!-- The daltonizer feature summary display as a subtext as an item in a list. -->
<string name="daltonizer_feature_summary" product="default">Adjust how colors display on your phone</string>
<!-- The daltonizer feature summary display as a subtext as an item in a list. -->
<string name="daltonizer_feature_summary" product="tablet">Adjust how colors display on your tablet</string>
</resources>

View File

@@ -12129,4 +12129,39 @@
<!-- Warning message when we try to dock an app not supporting multiple instances split into multiple sides [CHAR LIMIT=NONE] -->
<string name="dock_multi_instances_not_supported_text">"This app can only be opened in 1 window"</string>
<!-- The accessibility features state summary, indicating whether the service is turned on, whether the shortcut is turned on. The last part of the summary is the short summary of the feature. -->
<string name="accessibility_feature_full_state_summary"><xliff:g example="Service on" id="state">%1$s</xliff:g> / <xliff:g example="Shortcut on" id="shortcut_state">%2$s</xliff:g> / <xliff:g example="Speak items on screen" id="service_summary">%3$s</xliff:g></string>
<!-- Label representing that a generic Accessibility Service is turned on. -->
<string name="generic_accessibility_service_on">Service on</string>
<!-- Label representing that a generic Accessibility Service is turned off. -->
<string name="generic_accessibility_service_off">Service off</string>
<!-- Label representing that an accessibility feature's shortcut is turned off -->
<string name="generic_accessibility_feature_shortcut_off">Shortcut off</string>
<!-- Summary for the disabled state of the accessibility shortcut. This is shown as a summary for "[Service] shortcut", where "off" refers to the state of "shortcut". -->
<string name="accessibility_shortcut_state_off">Off</string>
<!-- Representing daltonizer (color filter) feature is turned on -->
<string name="daltonizer_state_on">On</string>
<!-- Representing daltonizer (color filter) feature is turned off -->
<string name="daltonizer_state_off">Off</string>
<!-- Representing color inversion feature is turned on -->
<string name="color_inversion_state_on">On</string>
<!-- Representing color inversion feature is turned off -->
<string name="color_inversion_state_off">Off</string>
<!-- The color inversion feature summary displayed as a subtext as an item in a list. -->
<string name="color_inversion_feature_summary">Turns light screens dark and dark screens light</string>
<!-- Short summary explains what magnification feature is. -->
<string name="magnification_feature_summary">Quickly zoom in on the screen to make content larger</string>
<!-- Summary of the AutoClick feature disabled state. -->
<string name="autoclick_disabled">Off</string>
<!-- Summary of the show captions preference disabled state. -->
<string name="show_captions_disabled">Off</string>
<!-- Summary of the show captions preference enabled state. -->
<string name="show_captions_enabled">On</string>
<!-- Summary of the Live Caption disabled state. -->
<string name="live_caption_disabled">Off</string>
<!-- Summary of the Live Caption enabled state. -->
<string name="live_caption_enabled">On</string>
</resources>

View File

@@ -34,7 +34,7 @@
android:persistent="false"
android:title="@string/one_handed_title"
settings:searchable="false"
settings:controller="com.android.settings.gestures.OneHandedEnablePreferenceController"/>
settings:controller="com.android.settings.accessibility.OneHandedPreferenceController"/>
<SwitchPreference
android:key="toggle_power_button_ends_call_preference"

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));
}
}

View File

@@ -139,6 +139,7 @@ public class AccessibilitySettingsTest {
mLifecycle = new Lifecycle(() -> mLifecycle);
when(mFragment.getSettingsLifecycle()).thenReturn(mLifecycle);
ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager;
setMockAccessibilityShortcutInfo(mShortcutInfo);
}
@Test
@@ -171,75 +172,157 @@ public class AccessibilitySettingsTest {
}
@Test
public void getServiceSummary_invisibleToggle_shortcutDisabled_showsOffSummary() {
public void getServiceSummary_invisibleToggle_shortcutEnabled_showsOnSummary() {
setInvisibleToggleFragmentType(mServiceInfo);
doReturn(DEFAULT_SUMMARY).when(mServiceInfo).loadSummary(any());
setShortcutEnabled(mServiceInfo.getComponentName(), true);
final CharSequence summary = AccessibilitySettings.getServiceSummary(mContext,
mServiceInfo, SERVICE_ENABLED);
assertThat(summary).isEqualTo(
mContext.getString(R.string.preference_summary_default_combination,
mContext.getString(R.string.accessibility_summary_shortcut_disabled),
mContext.getString(R.string.accessibility_summary_shortcut_enabled),
DEFAULT_SUMMARY));
}
@Test
public void getServiceSummary_enableService_showsEnabled() {
doReturn(EMPTY_STRING).when(mServiceInfo).loadSummary(any());
final CharSequence summary = AccessibilitySettings.getServiceSummary(mContext,
mServiceInfo, SERVICE_ENABLED);
assertThat(summary).isEqualTo(
mContext.getString(R.string.accessibility_summary_state_enabled));
}
@Test
public void getServiceSummary_disableService_showsDisabled() {
doReturn(EMPTY_STRING).when(mServiceInfo).loadSummary(any());
final CharSequence summary = AccessibilitySettings.getServiceSummary(mContext,
mServiceInfo, SERVICE_DISABLED);
assertThat(summary).isEqualTo(
mContext.getString(R.string.accessibility_summary_state_disabled));
}
@Test
public void getServiceSummary_enableServiceAndHasSummary_showsEnabledSummary() {
final String service_enabled = mContext.getString(
R.string.accessibility_summary_state_enabled);
public void getServiceSummary_invisibleToggle_shortcutDisabled_showsOffSummary() {
setInvisibleToggleFragmentType(mServiceInfo);
setShortcutEnabled(mServiceInfo.getComponentName(), false);
doReturn(DEFAULT_SUMMARY).when(mServiceInfo).loadSummary(any());
final CharSequence summary = AccessibilitySettings.getServiceSummary(mContext,
mServiceInfo, SERVICE_ENABLED);
assertThat(summary).isEqualTo(
mContext.getString(R.string.preference_summary_default_combination, service_enabled,
DEFAULT_SUMMARY));
}
@Test
public void getServiceSummary_disableServiceAndHasSummary_showsCombineDisabledSummary() {
final String service_disabled = mContext.getString(
R.string.accessibility_summary_state_disabled);
doReturn(DEFAULT_SUMMARY).when(mServiceInfo).loadSummary(any());
final CharSequence summary = AccessibilitySettings.getServiceSummary(mContext,
mServiceInfo, SERVICE_DISABLED);
assertThat(summary).isEqualTo(
mContext.getString(R.string.preference_summary_default_combination,
service_disabled, DEFAULT_SUMMARY));
mContext.getString(R.string.generic_accessibility_feature_shortcut_off),
DEFAULT_SUMMARY));
}
@Test
public void getServiceSummary_enableServiceShortcutOn_showsServiceEnabledShortcutOn() {
doReturn(EMPTY_STRING).when(mServiceInfo).loadSummary(any());
setShortcutEnabled(mServiceInfo.getComponentName(), true);
String summary = AccessibilitySettings.getServiceSummary(mContext,
mServiceInfo, SERVICE_ENABLED).toString();
assertThat(summary).isEqualTo(
mContext.getString(R.string.preference_summary_default_combination,
mContext.getString(R.string.generic_accessibility_service_on),
mContext.getString(R.string.accessibility_summary_shortcut_enabled)));
}
@Test
public void getServiceSummary_enableServiceShortcutOff_showsServiceEnabledShortcutOff() {
doReturn(EMPTY_STRING).when(mServiceInfo).loadSummary(any());
setShortcutEnabled(mServiceInfo.getComponentName(), false);
String summary = AccessibilitySettings.getServiceSummary(mContext,
mServiceInfo, SERVICE_ENABLED).toString();
assertThat(summary).isEqualTo(
mContext.getString(R.string.preference_summary_default_combination,
mContext.getString(R.string.generic_accessibility_service_on),
mContext.getString(R.string.generic_accessibility_feature_shortcut_off)));
}
@Test
public void getServiceSummary_disableServiceShortcutOff_showsDisabledShortcutOff() {
doReturn(EMPTY_STRING).when(mServiceInfo).loadSummary(any());
setShortcutEnabled(mServiceInfo.getComponentName(), false);
String summary = AccessibilitySettings.getServiceSummary(mContext,
mServiceInfo, SERVICE_DISABLED).toString();
assertThat(summary).isEqualTo(
mContext.getString(R.string.preference_summary_default_combination,
mContext.getString(R.string.generic_accessibility_service_off),
mContext.getString(R.string.generic_accessibility_feature_shortcut_off)));
}
@Test
public void getServiceSummary_disableServiceShortcutOn_showsDisabledShortcutOn() {
doReturn(EMPTY_STRING).when(mServiceInfo).loadSummary(any());
setShortcutEnabled(mServiceInfo.getComponentName(), true);
String summary = AccessibilitySettings.getServiceSummary(mContext,
mServiceInfo, SERVICE_DISABLED).toString();
assertThat(summary).isEqualTo(
mContext.getString(R.string.preference_summary_default_combination,
mContext.getString(R.string.generic_accessibility_service_off),
mContext.getString(R.string.accessibility_summary_shortcut_enabled)));
}
@Test
public void getServiceSummary_enableServiceShortcutOffAndHasSummary_showsEnabledShortcutOffSummary() {
setShortcutEnabled(mServiceInfo.getComponentName(), false);
doReturn(DEFAULT_SUMMARY).when(mServiceInfo).loadSummary(any());
String summary = AccessibilitySettings.getServiceSummary(mContext,
mServiceInfo, SERVICE_ENABLED).toString();
assertThat(summary).isEqualTo(
mContext.getString(R.string.accessibility_feature_full_state_summary,
mContext.getString(R.string.generic_accessibility_service_on),
mContext.getString(R.string.generic_accessibility_feature_shortcut_off),
DEFAULT_SUMMARY));
}
@Test
public void getServiceSummary_enableServiceShortcutOnAndHasSummary_showsEnabledShortcutOnSummary() {
doReturn(DEFAULT_SUMMARY).when(mServiceInfo).loadSummary(any());
setShortcutEnabled(mServiceInfo.getComponentName(), true);
String summary = AccessibilitySettings.getServiceSummary(mContext,
mServiceInfo, SERVICE_ENABLED).toString();
assertThat(summary).isEqualTo(
mContext.getString(R.string.accessibility_feature_full_state_summary,
mContext.getString(R.string.generic_accessibility_service_on),
mContext.getString(R.string.accessibility_summary_shortcut_enabled),
DEFAULT_SUMMARY));
}
@Test
public void getServiceSummary_disableServiceShortcutOnAndHasSummary_showsDisabledShortcutOnSummary() {
doReturn(DEFAULT_SUMMARY).when(mServiceInfo).loadSummary(any());
setShortcutEnabled(mServiceInfo.getComponentName(), true);
String summary = AccessibilitySettings.getServiceSummary(mContext,
mServiceInfo, SERVICE_DISABLED).toString();
assertThat(summary).isEqualTo(
mContext.getString(R.string.accessibility_feature_full_state_summary,
mContext.getString(R.string.generic_accessibility_service_off),
mContext.getString(R.string.accessibility_summary_shortcut_enabled),
DEFAULT_SUMMARY));
}
@Test
public void getServiceSummary_disableServiceShortcutOffAndHasSummary_showsDisabledShortcutOffSummary() {
setShortcutEnabled(mServiceInfo.getComponentName(), false);
doReturn(DEFAULT_SUMMARY).when(mServiceInfo).loadSummary(any());
String summary = AccessibilitySettings.getServiceSummary(mContext,
mServiceInfo, SERVICE_DISABLED).toString();
assertThat(summary).isEqualTo(
mContext.getString(R.string.accessibility_feature_full_state_summary,
mContext.getString(R.string.generic_accessibility_service_off),
mContext.getString(R.string.generic_accessibility_feature_shortcut_off),
DEFAULT_SUMMARY));
}
@Test
public void getServiceDescription_serviceCrash_showsStopped() {
mServiceInfo.crashed = true;
final CharSequence description = AccessibilitySettings.getServiceDescription(mContext,
mServiceInfo, SERVICE_ENABLED);
String description = AccessibilitySettings.getServiceDescription(mContext,
mServiceInfo, SERVICE_ENABLED).toString();
assertThat(description).isEqualTo(
mContext.getString(R.string.accessibility_description_state_stopped));
@@ -249,12 +332,42 @@ public class AccessibilitySettingsTest {
public void getServiceDescription_haveDescription_showsDescription() {
doReturn(DEFAULT_DESCRIPTION).when(mServiceInfo).loadDescription(any());
final CharSequence description = AccessibilitySettings.getServiceDescription(mContext,
mServiceInfo, SERVICE_ENABLED);
String description = AccessibilitySettings.getServiceDescription(mContext,
mServiceInfo, SERVICE_ENABLED).toString();
assertThat(description).isEqualTo(DEFAULT_DESCRIPTION);
}
@Test
public void getA11yShortcutInfoPreferenceSummary_shortcutOn_showsShortcutOnSummary() {
doReturn(DEFAULT_SUMMARY).when(mShortcutInfo).loadSummary(any());
setShortcutEnabled(COMPONENT_NAME, true);
String summary = AccessibilitySettings.getA11yShortcutInfoPreferenceSummary(
mContext,
mShortcutInfo).toString();
assertThat(summary).isEqualTo(
mContext.getString(R.string.preference_summary_default_combination,
mContext.getString(R.string.accessibility_summary_shortcut_enabled),
DEFAULT_SUMMARY));
}
@Test
public void getA11yShortcutInfoPreferenceSummary_shortcutOff_showsShortcutOffSummary() {
doReturn(DEFAULT_SUMMARY).when(mShortcutInfo).loadSummary(any());
setShortcutEnabled(COMPONENT_NAME, false);
String summary = AccessibilitySettings.getA11yShortcutInfoPreferenceSummary(
mContext,
mShortcutInfo).toString();
assertThat(summary).isEqualTo(
mContext.getString(R.string.preference_summary_default_combination,
mContext.getString(R.string.generic_accessibility_feature_shortcut_off),
DEFAULT_SUMMARY));
}
@Test
@Config(shadows = {ShadowFragment.class, ShadowUserManager.class})
public void onCreate_haveRegisterToSpecificUrisAndActions() {
@@ -269,7 +382,7 @@ public class AccessibilitySettingsTest {
anyBoolean(),
any(AccessibilitySettingsContentObserver.class));
verify(mContentResolver).registerContentObserver(eq(Settings.Secure.getUriFor(
Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE)), anyBoolean(),
Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE)), anyBoolean(),
any(AccessibilitySettingsContentObserver.class));
verify(mActivity, atLeast(1)).registerReceiver(any(PackageMonitor.class), captor.capture(),
isNull(), any());
@@ -403,4 +516,10 @@ public class AccessibilitySettingsTest {
mFragment.onStart();
mFragment.onResume();
}
private void setShortcutEnabled(ComponentName componentName, boolean enabled) {
Settings.Secure.putString(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
enabled ? componentName.flattenToString() : "");
}
}

View File

@@ -27,6 +27,8 @@ import android.content.pm.ServiceInfo;
import android.os.Build;
import android.provider.Settings;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.accessibility.AccessibilityUtil.UserShortcutType;
@@ -34,33 +36,33 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.util.StringJoiner;
@RunWith(RobolectricTestRunner.class)
public final class AccessibilityUtilTest {
private static final int ON = 1;
private static final int OFF = 0;
private static final String SECURE_TEST_KEY = "secure_test_key";
private static final String DUMMY_PACKAGE_NAME = "com.mock.example";
private static final String DUMMY_CLASS_NAME = DUMMY_PACKAGE_NAME + ".mock_a11y_service";
private static final String DUMMY_CLASS_NAME2 = DUMMY_PACKAGE_NAME + ".mock_a11y_service2";
private static final ComponentName DUMMY_COMPONENT_NAME = new ComponentName(DUMMY_PACKAGE_NAME,
DUMMY_CLASS_NAME);
private static final ComponentName DUMMY_COMPONENT_NAME2 = new ComponentName(DUMMY_PACKAGE_NAME,
DUMMY_CLASS_NAME2);
private static final String MOCK_PACKAGE_NAME = "com.mock.example";
private static final String MOCK_CLASS_NAME = MOCK_PACKAGE_NAME + ".mock_a11y_service";
private static final String MOCK_CLASS_NAME2 = MOCK_PACKAGE_NAME + ".mock_a11y_service2";
private static final ComponentName MOCK_COMPONENT_NAME = new ComponentName(MOCK_PACKAGE_NAME,
MOCK_CLASS_NAME);
private static final ComponentName MOCK_COMPONENT_NAME2 = new ComponentName(MOCK_PACKAGE_NAME,
MOCK_CLASS_NAME2);
private static final String SOFTWARE_SHORTCUT_KEY =
Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS;
private static final String HARDWARE_SHORTCUT_KEY =
Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE;
private static final String PLACEHOLDER_SETTING_FEATURE = "placeholderSettingFeature";
private Context mContext;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
mContext = ApplicationProvider.getApplicationContext();
}
@Test
@@ -75,30 +77,33 @@ public final class AccessibilityUtilTest {
@Test
public void getSummary_hasValueAndEqualsToOne_shouldReturnOnString() {
Settings.Secure.putInt(mContext.getContentResolver(), SECURE_TEST_KEY, ON);
setSettingsFeatureEnabled(SECURE_TEST_KEY, true);
final CharSequence result = AccessibilityUtil.getSummary(mContext, SECURE_TEST_KEY);
final CharSequence result = AccessibilityUtil.getSummary(mContext, SECURE_TEST_KEY,
R.string.switch_on_text, R.string.switch_off_text);
assertThat(result)
.isEqualTo(mContext.getText(R.string.accessibility_feature_state_on));
.isEqualTo(mContext.getText(R.string.switch_on_text));
}
@Test
public void getSummary_hasValueAndEqualsToZero_shouldReturnOffString() {
Settings.Secure.putInt(mContext.getContentResolver(), SECURE_TEST_KEY, OFF);
setSettingsFeatureEnabled(SECURE_TEST_KEY, false);
final CharSequence result = AccessibilityUtil.getSummary(mContext, SECURE_TEST_KEY);
final CharSequence result = AccessibilityUtil.getSummary(mContext, SECURE_TEST_KEY,
R.string.switch_on_text, R.string.switch_off_text);
assertThat(result)
.isEqualTo(mContext.getText(R.string.accessibility_feature_state_off));
.isEqualTo(mContext.getText(R.string.switch_off_text));
}
@Test
public void getSummary_noValue_shouldReturnOffString() {
final CharSequence result = AccessibilityUtil.getSummary(mContext, SECURE_TEST_KEY);
final CharSequence result = AccessibilityUtil.getSummary(mContext, SECURE_TEST_KEY,
R.string.switch_on_text, R.string.switch_off_text);
assertThat(result)
.isEqualTo(mContext.getText(R.string.accessibility_feature_state_off));
.isEqualTo(mContext.getText(R.string.switch_off_text));
}
@Test
@@ -136,29 +141,31 @@ public final class AccessibilityUtilTest {
@Test
public void hasValueInSettings_putValue_hasValue() {
putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, DUMMY_COMPONENT_NAME.flattenToString());
setShortcut(UserShortcutType.SOFTWARE, MOCK_COMPONENT_NAME.flattenToString());
assertThat(AccessibilityUtil.hasValueInSettings(mContext, UserShortcutType.SOFTWARE,
DUMMY_COMPONENT_NAME)).isTrue();
MOCK_COMPONENT_NAME)).isTrue();
}
@Test
public void getUserShortcutTypeFromSettings_putOneValue_hasValue() {
putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, DUMMY_COMPONENT_NAME.flattenToString());
setShortcut(UserShortcutType.SOFTWARE, MOCK_COMPONENT_NAME.flattenToString());
final int shortcutType = AccessibilityUtil.getUserShortcutTypesFromSettings(mContext,
DUMMY_COMPONENT_NAME);
MOCK_COMPONENT_NAME);
assertThat(
(shortcutType & UserShortcutType.SOFTWARE) == UserShortcutType.SOFTWARE).isTrue();
}
@Test
public void getUserShortcutTypeFromSettings_putTwoValues_hasValue() {
putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, DUMMY_COMPONENT_NAME.flattenToString());
putStringIntoSettings(HARDWARE_SHORTCUT_KEY, DUMMY_COMPONENT_NAME.flattenToString());
setShortcut(UserShortcutType.SOFTWARE, MOCK_COMPONENT_NAME.flattenToString());
setShortcut(UserShortcutType.HARDWARE, MOCK_COMPONENT_NAME.flattenToString());
final int shortcutType = AccessibilityUtil.getUserShortcutTypesFromSettings(mContext,
DUMMY_COMPONENT_NAME);
MOCK_COMPONENT_NAME);
assertThat(
(shortcutType & UserShortcutType.SOFTWARE) == UserShortcutType.SOFTWARE).isTrue();
assertThat(
@@ -167,50 +174,53 @@ public final class AccessibilityUtilTest {
@Test
public void optInAllValuesToSettings_optInValue_haveMatchString() {
clearShortcuts();
int shortcutTypes = UserShortcutType.SOFTWARE | UserShortcutType.HARDWARE;
AccessibilityUtil.optInAllValuesToSettings(mContext, shortcutTypes, DUMMY_COMPONENT_NAME);
AccessibilityUtil.optInAllValuesToSettings(mContext, shortcutTypes, MOCK_COMPONENT_NAME);
assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEqualTo(
DUMMY_COMPONENT_NAME.flattenToString());
MOCK_COMPONENT_NAME.flattenToString());
assertThat(getStringFromSettings(HARDWARE_SHORTCUT_KEY)).isEqualTo(
DUMMY_COMPONENT_NAME.flattenToString());
MOCK_COMPONENT_NAME.flattenToString());
}
@Test
public void optInValueToSettings_optInValue_haveMatchString() {
putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, DUMMY_COMPONENT_NAME.flattenToString());
setShortcut(UserShortcutType.SOFTWARE, MOCK_COMPONENT_NAME.flattenToString());
AccessibilityUtil.optInValueToSettings(mContext, UserShortcutType.SOFTWARE,
DUMMY_COMPONENT_NAME2);
MOCK_COMPONENT_NAME2);
assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEqualTo(
DUMMY_COMPONENT_NAME.flattenToString() + ":"
+ DUMMY_COMPONENT_NAME2.flattenToString());
MOCK_COMPONENT_NAME.flattenToString() + ":"
+ MOCK_COMPONENT_NAME2.flattenToString());
}
@Test
public void optInValueToSettings_optInTwoValues_haveMatchString() {
putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, DUMMY_COMPONENT_NAME.flattenToString());
setShortcut(UserShortcutType.SOFTWARE, MOCK_COMPONENT_NAME.flattenToString());
AccessibilityUtil.optInValueToSettings(mContext, UserShortcutType.SOFTWARE,
DUMMY_COMPONENT_NAME2);
MOCK_COMPONENT_NAME2);
AccessibilityUtil.optInValueToSettings(mContext, UserShortcutType.SOFTWARE,
DUMMY_COMPONENT_NAME2);
MOCK_COMPONENT_NAME2);
assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEqualTo(
DUMMY_COMPONENT_NAME.flattenToString() + ":"
+ DUMMY_COMPONENT_NAME2.flattenToString());
MOCK_COMPONENT_NAME.flattenToString() + ":"
+ MOCK_COMPONENT_NAME2.flattenToString());
}
@Test
public void optOutAllValuesToSettings_optOutValue_emptyString() {
putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, DUMMY_COMPONENT_NAME.flattenToString());
putStringIntoSettings(HARDWARE_SHORTCUT_KEY, DUMMY_COMPONENT_NAME.flattenToString());
setShortcut(UserShortcutType.SOFTWARE, MOCK_COMPONENT_NAME.flattenToString());
setShortcut(UserShortcutType.HARDWARE, MOCK_COMPONENT_NAME.flattenToString());
int shortcutTypes =
UserShortcutType.SOFTWARE | UserShortcutType.HARDWARE | UserShortcutType.TRIPLETAP;
AccessibilityUtil.optOutAllValuesFromSettings(mContext, shortcutTypes,
DUMMY_COMPONENT_NAME);
MOCK_COMPONENT_NAME);
assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEmpty();
assertThat(getStringFromSettings(HARDWARE_SHORTCUT_KEY)).isEmpty();
@@ -218,30 +228,108 @@ public final class AccessibilityUtilTest {
@Test
public void optOutValueFromSettings_optOutValue_emptyString() {
putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, DUMMY_COMPONENT_NAME.flattenToString());
setShortcut(UserShortcutType.SOFTWARE, MOCK_COMPONENT_NAME.flattenToString());
AccessibilityUtil.optOutValueFromSettings(mContext, UserShortcutType.SOFTWARE,
DUMMY_COMPONENT_NAME);
MOCK_COMPONENT_NAME);
assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEmpty();
}
@Test
public void optOutValueFromSettings_optOutValue_haveMatchString() {
putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, DUMMY_COMPONENT_NAME.flattenToString() + ":"
+ DUMMY_COMPONENT_NAME2.flattenToString());
setShortcut(UserShortcutType.SOFTWARE, MOCK_COMPONENT_NAME.flattenToString(),
MOCK_COMPONENT_NAME2.flattenToString());
AccessibilityUtil.optOutValueFromSettings(mContext, UserShortcutType.SOFTWARE,
DUMMY_COMPONENT_NAME2);
MOCK_COMPONENT_NAME2);
assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEqualTo(
DUMMY_COMPONENT_NAME.flattenToString());
MOCK_COMPONENT_NAME.flattenToString());
}
@Test
public void getFeatureFullStateSummary_featureOffShortcutOff_showsOffShortcutOffAndSummary() {
setSettingsFeatureEnabled(PLACEHOLDER_SETTING_FEATURE, false);
clearShortcuts();
String expectedText = mContext.getString(
R.string.accessibility_feature_full_state_summary,
mContext.getString(R.string.color_inversion_state_off),
mContext.getString(R.string.generic_accessibility_feature_shortcut_off),
mContext.getString(R.string.color_inversion_feature_summary));
String observerText = AccessibilityUtil.getFeatureFullStateSummary(
mContext, MOCK_COMPONENT_NAME,
PLACEHOLDER_SETTING_FEATURE,
R.string.color_inversion_state_on, R.string.color_inversion_state_off,
R.string.color_inversion_feature_summary).toString();
assertThat(observerText).isEqualTo(expectedText);
}
@Test
public void getFeatureFullStateSummary_featureOnShortcutOff_showsOnShortcutOffAndSummary() {
setSettingsFeatureEnabled(PLACEHOLDER_SETTING_FEATURE, true);
clearShortcuts();
String expectedText = mContext.getString(
R.string.accessibility_feature_full_state_summary,
mContext.getString(R.string.color_inversion_state_on),
mContext.getString(R.string.generic_accessibility_feature_shortcut_off),
mContext.getString(R.string.color_inversion_feature_summary));
String observerText = AccessibilityUtil.getFeatureFullStateSummary(
mContext, MOCK_COMPONENT_NAME,
PLACEHOLDER_SETTING_FEATURE,
R.string.color_inversion_state_on, R.string.color_inversion_state_off,
R.string.color_inversion_feature_summary).toString();
assertThat(observerText).isEqualTo(expectedText);
}
@Test
public void getFeatureFullStateSummary_featureOffShortcutOn_showsOffShortcutOnAndSummary() {
setSettingsFeatureEnabled(PLACEHOLDER_SETTING_FEATURE, false);
setShortcut(UserShortcutType.SOFTWARE, MOCK_COMPONENT_NAME.flattenToString());
String expectedText = mContext.getString(
R.string.accessibility_feature_full_state_summary,
mContext.getString(R.string.color_inversion_state_off),
mContext.getString(R.string.accessibility_summary_shortcut_enabled),
mContext.getString(R.string.color_inversion_feature_summary));
String observerText = AccessibilityUtil.getFeatureFullStateSummary(
mContext, MOCK_COMPONENT_NAME,
PLACEHOLDER_SETTING_FEATURE,
R.string.color_inversion_state_on, R.string.color_inversion_state_off,
R.string.color_inversion_feature_summary).toString();
assertThat(observerText).isEqualTo(expectedText);
}
@Test
public void getFeatureFullStateSummary_featureOnShortcutOn_showsOnShortcutOnAndSummary() {
setSettingsFeatureEnabled(PLACEHOLDER_SETTING_FEATURE, true);
setShortcut(UserShortcutType.SOFTWARE, MOCK_COMPONENT_NAME.flattenToString());
String expectedText = mContext.getString(
R.string.accessibility_feature_full_state_summary,
mContext.getString(R.string.color_inversion_state_on),
mContext.getString(R.string.accessibility_summary_shortcut_enabled),
mContext.getString(R.string.color_inversion_feature_summary));
String observerText = AccessibilityUtil.getFeatureFullStateSummary(
mContext, MOCK_COMPONENT_NAME,
PLACEHOLDER_SETTING_FEATURE,
R.string.color_inversion_state_on, R.string.color_inversion_state_off,
R.string.color_inversion_feature_summary).toString();
assertThat(observerText).isEqualTo(expectedText);
}
private AccessibilityServiceInfo getMockAccessibilityServiceInfo() {
final ApplicationInfo applicationInfo = new ApplicationInfo();
final ServiceInfo serviceInfo = new ServiceInfo();
applicationInfo.packageName = DUMMY_PACKAGE_NAME;
serviceInfo.packageName = DUMMY_PACKAGE_NAME;
serviceInfo.name = DUMMY_CLASS_NAME;
applicationInfo.packageName = MOCK_PACKAGE_NAME;
serviceInfo.packageName = MOCK_PACKAGE_NAME;
serviceInfo.name = MOCK_CLASS_NAME;
serviceInfo.applicationInfo = applicationInfo;
final ResolveInfo resolveInfo = new ResolveInfo();
@@ -250,7 +338,7 @@ public final class AccessibilityUtilTest {
try {
final AccessibilityServiceInfo info = new AccessibilityServiceInfo(resolveInfo,
mContext);
info.setComponentName(DUMMY_COMPONENT_NAME);
info.setComponentName(MOCK_COMPONENT_NAME);
return info;
} catch (XmlPullParserException | IOException e) {
// Do nothing
@@ -259,11 +347,28 @@ public final class AccessibilityUtilTest {
return null;
}
private void putStringIntoSettings(String key, String componentName) {
Settings.Secure.putString(mContext.getContentResolver(), key, componentName);
}
private String getStringFromSettings(String key) {
return Settings.Secure.getString(mContext.getContentResolver(), key);
}
private void setSettingsFeatureEnabled(String settingsKey, boolean enabled) {
Settings.Secure.putInt(mContext.getContentResolver(),
settingsKey,
enabled ? AccessibilityUtil.State.ON : AccessibilityUtil.State.OFF);
}
private void setShortcut(@UserShortcutType int shortcutType, String... componentNames) {
StringJoiner shortcutComponents = new StringJoiner(":");
for (String componentName : componentNames) {
shortcutComponents.add(componentName);
}
Settings.Secure.putString(mContext.getContentResolver(),
shortcutType == UserShortcutType.SOFTWARE ? SOFTWARE_SHORTCUT_KEY
: HARDWARE_SHORTCUT_KEY, shortcutComponents.toString());
}
private void clearShortcuts() {
Settings.Secure.putString(mContext.getContentResolver(), SOFTWARE_SHORTCUT_KEY, "");
Settings.Secure.putString(mContext.getContentResolver(), HARDWARE_SHORTCUT_KEY, "");
}
}

View File

@@ -56,19 +56,17 @@ public class AutoclickPreferenceControllerTest {
@Test
public void getSummary_disabledAutoclick_shouldReturnOffSummary() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED, OFF);
setAutoClickEnabled(false);
assertThat(mController.getSummary())
.isEqualTo(mContext.getText(R.string.accessibility_feature_state_off));
assertThat(mController.getSummary().toString())
.isEqualTo(mContext.getText(R.string.autoclick_disabled));
}
@Test
public void getSummary_enabledAutoclick_shouldReturnOnSummary() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED, ON);
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_AUTOCLICK_DELAY, AUTOCLICK_DELAY_DEFAULT);
setAutoClickEnabled(true);
setAutoClickDelayed(AUTOCLICK_DELAY_DEFAULT);
assertThat(mController.getSummary().toString())
.isEqualTo(AutoclickUtils.getAutoclickDelaySummary(
@@ -76,4 +74,14 @@ public class AutoclickPreferenceControllerTest {
R.string.accessibilty_autoclick_preference_subtitle_medium_delay,
AUTOCLICK_DELAY_DEFAULT).toString());
}
private void setAutoClickEnabled(boolean enabled) {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED, enabled ? ON : OFF);
}
private void setAutoClickDelayed(int delayedInMs) {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_AUTOCLICK_DELAY, delayedInMs);
}
}

View File

@@ -24,6 +24,8 @@ import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.provider.Settings;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
@@ -31,7 +33,6 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
/** Tests for {@link CaptioningPreferenceController}. */
@RunWith(RobolectricTestRunner.class)
@@ -42,7 +43,7 @@ public class CaptioningPreferenceControllerTest {
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
mContext = ApplicationProvider.getApplicationContext();
mController = new CaptioningPreferenceController(mContext, "captioning_pref");
}
@@ -54,19 +55,22 @@ public class CaptioningPreferenceControllerTest {
@Test
public void getSummary_enabledCaptions_shouldReturnOnSummary() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, ON);
setCaptioningEnabled(true);
assertThat(mController.getSummary()).isEqualTo(
mContext.getText(R.string.accessibility_feature_state_on));
mContext.getText(R.string.show_captions_enabled));
}
@Test
public void getSummary_disabledCaptions_shouldReturnOffSummary() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, OFF);
setCaptioningEnabled(false);
assertThat(mController.getSummary()).isEqualTo(
mContext.getText(R.string.accessibility_feature_state_off));
mContext.getText(R.string.show_captions_disabled));
}
private void setCaptioningEnabled(boolean enabled) {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED, enabled ? ON : OFF);
}
}

View File

@@ -16,18 +16,21 @@
package com.android.settings.accessibility;
import static com.android.internal.accessibility.AccessibilityShortcutController.COLOR_INVERSION_COMPONENT_NAME;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.provider.Settings;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -39,29 +42,72 @@ public class ColorInversionPreferenceControllerTest {
Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED;
private Context mContext;
private ColorInversionPreferenceController mController;
private String mColorInversionSummary;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
mContext = ApplicationProvider.getApplicationContext();
mController = new ColorInversionPreferenceController(mContext, PREF_KEY);
mColorInversionSummary = mContext.getString(R.string.color_inversion_feature_summary);
}
@Test
public void getSummary_enabledColorInversion_shouldReturnOnSummary() {
Settings.Secure.putInt(mContext.getContentResolver(),
DISPLAY_INVERSION_ENABLED, State.ON);
public void getSummary_enabledColorInversionShortcutOff_shouldReturnOnShortcutOffSummary() {
setColorInversionEnabled(true);
setColorInversionShortcutEnabled(false);
assertThat(mController.getSummary().toString().contains(
mContext.getText(R.string.accessibility_feature_state_on))).isTrue();
assertThat(mController.getSummary().toString()).isEqualTo(
mContext.getString(R.string.accessibility_feature_full_state_summary,
mContext.getString(R.string.color_inversion_state_on),
mContext.getString(R.string.generic_accessibility_feature_shortcut_off),
mColorInversionSummary));
}
@Test
public void getSummary_disabledColorInversion_shouldReturnOffSummary() {
Settings.Secure.putInt(mContext.getContentResolver(),
DISPLAY_INVERSION_ENABLED, State.OFF);
public void getSummary_enabledColorInversionShortcutOn_shouldReturnOnShortcutOnSummary() {
setColorInversionEnabled(true);
setColorInversionShortcutEnabled(true);
assertThat(mController.getSummary().toString().contains(
mContext.getText(R.string.accessibility_feature_state_off))).isTrue();
assertThat(mController.getSummary().toString()).isEqualTo(
mContext.getString(R.string.accessibility_feature_full_state_summary,
mContext.getString(R.string.color_inversion_state_on),
mContext.getString(R.string.accessibility_summary_shortcut_enabled),
mColorInversionSummary));
}
@Test
public void getSummary_disabledColorInversionShortcutOff_shouldReturnOffShortcutOffSummary() {
setColorInversionEnabled(false);
setColorInversionShortcutEnabled(false);
assertThat(mController.getSummary().toString()).isEqualTo(
mContext.getString(R.string.accessibility_feature_full_state_summary,
mContext.getString(R.string.color_inversion_state_off),
mContext.getString(R.string.generic_accessibility_feature_shortcut_off),
mColorInversionSummary));
}
@Test
public void getSummary_disabledColorInversionShortcutOn_shouldReturnOffShortcutOnSummary() {
setColorInversionEnabled(false);
setColorInversionShortcutEnabled(true);
assertThat(mController.getSummary().toString()).isEqualTo(
mContext.getString(R.string.accessibility_feature_full_state_summary,
mContext.getString(R.string.color_inversion_state_off),
mContext.getString(R.string.accessibility_summary_shortcut_enabled),
mColorInversionSummary));
}
private void setColorInversionShortcutEnabled(boolean enabled) {
Settings.Secure.putString(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
enabled ? COLOR_INVERSION_COMPONENT_NAME.flattenToString() : "");
}
private void setColorInversionEnabled(boolean enabled) {
Settings.Secure.putInt(mContext.getContentResolver(),
DISPLAY_INVERSION_ENABLED, enabled ? State.ON : State.OFF);
}
@Retention(RetentionPolicy.SOURCE)

View File

@@ -16,18 +16,21 @@
package com.android.settings.accessibility;
import static com.android.internal.accessibility.AccessibilityShortcutController.DALTONIZER_COMPONENT_NAME;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.provider.Settings;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class)
public class DaltonizerPreferenceControllerTest {
@@ -37,28 +40,71 @@ public class DaltonizerPreferenceControllerTest {
private Context mContext;
private DaltonizerPreferenceController mController;
private String mDaltonizerSummary;
@Before
public void setUp() {
mContext = RuntimeEnvironment.application;
mContext = ApplicationProvider.getApplicationContext();
mController = new DaltonizerPreferenceController(mContext, PREF_KEY);
mDaltonizerSummary = mContext.getString(R.string.daltonizer_feature_summary);
}
@Test
public void getSummary_enabledColorCorrection_shouldReturnOnSummary() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, ON);
public void getSummary_enabledColorCorrectionShortcutOff_shouldReturnOnShortcutOffSummary() {
setColorCorrectionEnabled(true);
setColorCorrectionShortcutEnabled(false);
assertThat(mController.getSummary().toString().contains(
mContext.getText(R.string.accessibility_feature_state_on))).isTrue();
assertThat(mController.getSummary().toString()).isEqualTo(
mContext.getString(R.string.accessibility_feature_full_state_summary,
mContext.getString(R.string.daltonizer_state_on),
mContext.getString(R.string.generic_accessibility_feature_shortcut_off),
mDaltonizerSummary));
}
@Test
public void getSummary_disabledColorCorrection_shouldReturnOffSummary() {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, OFF);
public void getSummary_enabledColorCorrectionShortcutOn_shouldReturnOnShortcutOnSummary() {
setColorCorrectionEnabled(true);
setColorCorrectionShortcutEnabled(true);
assertThat(mController.getSummary().toString().contains(
mContext.getText(R.string.accessibility_feature_state_off))).isTrue();
assertThat(mController.getSummary().toString()).isEqualTo(
mContext.getString(R.string.accessibility_feature_full_state_summary,
mContext.getString(R.string.daltonizer_state_on),
mContext.getString(R.string.accessibility_summary_shortcut_enabled),
mDaltonizerSummary));
}
@Test
public void getSummary_disabledColorCorrectionShortcutOff_shouldReturnOffShortcutOffSummary() {
setColorCorrectionEnabled(false);
setColorCorrectionShortcutEnabled(false);
assertThat(mController.getSummary().toString()).isEqualTo(
mContext.getString(R.string.accessibility_feature_full_state_summary,
mContext.getString(R.string.daltonizer_state_off),
mContext.getString(R.string.generic_accessibility_feature_shortcut_off),
mDaltonizerSummary));
}
@Test
public void getSummary_disabledColorCorrectionShortcutOn_shouldReturnOffShortcutOnSummary() {
setColorCorrectionEnabled(false);
setColorCorrectionShortcutEnabled(true);
assertThat(mController.getSummary().toString()).isEqualTo(
mContext.getString(R.string.accessibility_feature_full_state_summary,
mContext.getString(R.string.daltonizer_state_off),
mContext.getString(R.string.accessibility_summary_shortcut_enabled),
mDaltonizerSummary));
}
private void setColorCorrectionEnabled(boolean enabled) {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, enabled ? ON : OFF);
}
private void setColorCorrectionShortcutEnabled(boolean enabled) {
Settings.Secure.putString(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
enabled ? DALTONIZER_COMPONENT_NAME.flattenToString() : "");
}
}

View File

@@ -21,13 +21,19 @@ import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.content.pm.ResolveInfo;
import android.provider.Settings;
import androidx.preference.Preference;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
import org.robolectric.shadows.ShadowPackageManager;
@@ -36,18 +42,20 @@ import java.util.Collections;
@RunWith(RobolectricTestRunner.class)
public class LiveCaptionPreferenceControllerTest {
private Context mContext;
private LiveCaptionPreferenceController mController;
private Preference mLiveCaptionPreference;
@Before
public void setUp() {
mController = new LiveCaptionPreferenceController(RuntimeEnvironment.application,
"test_key");
mContext = ApplicationProvider.getApplicationContext();
mController = new LiveCaptionPreferenceController(mContext, "test_key");
mLiveCaptionPreference = new Preference(mContext);
}
@Test
public void getAvailabilityStatus_canResolveIntent_shouldReturnAvailable() {
final ShadowPackageManager pm = Shadows.shadowOf(
RuntimeEnvironment.application.getPackageManager());
final ShadowPackageManager pm = Shadows.shadowOf(mContext.getPackageManager());
pm.addResolveInfoForIntent(LiveCaptionPreferenceController.LIVE_CAPTION_INTENT,
new ResolveInfo());
@@ -56,11 +64,43 @@ public class LiveCaptionPreferenceControllerTest {
@Test
public void getAvailabilityStatus_noResolveIntent_shouldReturnUnavailable() {
final ShadowPackageManager pm = Shadows.shadowOf(
RuntimeEnvironment.application.getPackageManager());
final ShadowPackageManager pm = Shadows.shadowOf(mContext.getPackageManager());
pm.setResolveInfosForIntent(LiveCaptionPreferenceController.LIVE_CAPTION_INTENT,
Collections.emptyList());
assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
}
@Test
public void updateState_liveCaptionEnabled_subtextShowsOnSummary() {
setLiveCaptionEnabled(true);
mController.updateState(mLiveCaptionPreference);
assertThat(mLiveCaptionPreference.getSummary().toString()).isEqualTo(
mContext.getString(
R.string.preference_summary_default_combination,
mContext.getString(R.string.live_caption_enabled),
mContext.getText(R.string.live_caption_summary))
);
}
@Test
public void updateState_liveCaptionDisabled_subtextShowsOffSummary() {
setLiveCaptionEnabled(false);
mController.updateState(mLiveCaptionPreference);
assertThat(mLiveCaptionPreference.getSummary()).isEqualTo(
mContext.getString(
R.string.preference_summary_default_combination,
mContext.getString(R.string.live_caption_disabled),
mContext.getText(R.string.live_caption_summary))
);
}
private void setLiveCaptionEnabled(boolean enabled) {
Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.ODI_CAPTIONS_ENABLED,
enabled ? AccessibilityUtil.State.ON: AccessibilityUtil.State.OFF);
}
}

View File

@@ -411,6 +411,31 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
assertTrue(arguments.containsKey(AccessibilitySettings.EXTRA_HTML_DESCRIPTION));
}
@Test
public void getSummary_magnificationEnabled_returnShortcutOnWithSummary() {
setMagnificationTripleTapEnabled(true);
assertThat(
ToggleScreenMagnificationPreferenceFragment.getServiceSummary(mContext).toString())
.isEqualTo(
mContext.getString(R.string.preference_summary_default_combination,
mContext.getString(R.string.accessibility_summary_shortcut_enabled),
mContext.getText(R.string.magnification_feature_summary)));
}
@Test
public void getSummary_magnificationDisabled_returnShortcutOffWithSummary() {
setMagnificationTripleTapEnabled(false);
assertThat(
ToggleScreenMagnificationPreferenceFragment.getServiceSummary(mContext).toString())
.isEqualTo(
mContext.getString(R.string.preference_summary_default_combination,
mContext.getString(
R.string.generic_accessibility_feature_shortcut_off),
mContext.getText(R.string.magnification_feature_summary)));
}
private void putStringIntoSettings(String key, String componentName) {
Settings.Secure.putString(mContext.getContentResolver(), key, componentName);
}

View File

@@ -0,0 +1,63 @@
/*
* 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 static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.R;
import com.android.settings.gestures.OneHandedSettingsUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public final class OneHandedPreferenceControllerTest {
private Context mContext;
private OneHandedPreferenceController mController;
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
mController = new OneHandedPreferenceController(mContext, "one_handed");
}
@Test
public void getSummary_oneHandedEnabled_showsOnWithSummary() {
OneHandedSettingsUtils.setOneHandedModeEnabled(mContext, true);
assertThat(mController.getSummary().toString()).isEqualTo(
mContext.getString(R.string.preference_summary_default_combination,
mContext.getText(R.string.gesture_setting_on),
mContext.getText(R.string.one_handed_mode_intro_text)));
}
@Test
public void getSummary_oneHandedDisabled_showsOffWithSummary() {
OneHandedSettingsUtils.setOneHandedModeEnabled(mContext, false);
assertThat(mController.getSummary().toString()).isEqualTo(
mContext.getString(R.string.preference_summary_default_combination,
mContext.getText(R.string.gesture_setting_off),
mContext.getText(R.string.one_handed_mode_intro_text)));
}
}