diff --git a/res/values/strings.xml b/res/values/strings.xml index f8c58ce937b..2bef92c5be1 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -4865,33 +4865,45 @@ Page %1$d of %2$d - Use accessibility button to open + Accessibility button shortcut - Hold volume keys to open + Volume keys shortcut - Triple tap screen to open + Triple tap shortcut - Two finger double tap screen to open + %1$d-finger double tap shortcut Quick Settings shortcut - Use gesture to open + Accessibility gesture shortcut Use accessibility gesture - To use this feature, tap the accessibility button %s on the bottom of your screen.\n\nTo switch between features, touch & hold the accessibility button. + To use this feature, tap the accessibility button %s at the bottom of your screen.\n\nTo switch between features, touch & hold the accessibility button. - To use this feature, tap the accessibility button on your screen. + To use this feature, tap the accessibility button on your screen - To use this feature, press & hold both volume keys. - + To use this feature, press & hold both volume keys + To start and stop magnification, triple-tap anywhere on your screen. - - To start and stop magnification, double-tap anywhere on your screen with two fingers. - - To use this feature, swipe down from the top of your screen. + + To start and stop magnification, quickly tap the screen %1$d times + + To start and stop magnification, quickly tap the screen twice with %1$d fingers + + {count, plural, + =1 {To use this feature, swipe down from the top of your screen. Then, find the {featureName} tile.} + other {To use this feature, swipe down from the top of your screen with # fingers. Then, find the {featureName} tile.} + } + + This shortcut will be available after you finish device setup. To use this feature, swipe up from the bottom of the screen with 2 fingers.\n\nTo switch between features, swipe up with 2 fingers and hold. + + {count, plural, + =1 {To use this feature, swipe up from the bottom of your screen} + other {To use this feature, swipe up with # fingers from the bottom of your screen} + } To use this feature, swipe up from the bottom of the screen with 3 fingers.\n\nTo switch between features, swipe up with 3 fingers and hold. @@ -4901,7 +4913,9 @@ Got it - Button settings + Customize button + + More options %1$s shortcut @@ -4912,16 +4926,23 @@ Swipe up with 2 fingers Swipe up with 3 fingers - - Tap accessibility button - - Use accessibility gesture + + Accessibility button + + Tap the floating button + + Accessibility gesture - Tap the accessibility button %s at the bottom of your screen.\n\nTo switch between features, touch & hold the accessibility button. + Tap the accessibility button %s at the bottom of your screen. To switch between features, touch & hold the accessibility button. Swipe up from the bottom of the screen with 2 fingers.\n\nTo switch between features, swipe up with 2 fingers and hold. Swipe up from the bottom of the screen with 3 fingers.\n\nTo switch between features, swipe up with 3 fingers and hold. + + {count, plural, + =1 {Swipe up from the bottom of your screen. To switch between features, swipe up and hold.} + other {Swipe up with # fingers from the bottom of your screen. To switch between features, swipe up with # fingers and hold.} + } More options @@ -4929,25 +4950,41 @@ Quick Settings - Swipe down from the top of your screen + {count, plural, + =1 {Swipe down from the top of your screen} + other {Swipe down with # fingers from the top of your screen} + } + + {count, plural, + =1 {Swipe down from the top of your screen. This shortcut will be available after you finish device setup.} + other {Swipe down with # fingers from the top of your screen. This shortcut will be available after you finish device setup.} + } Quick Settings - Hold volume keys + Volume keys - hold volume keys + volume keys Press & hold both volume keys Two-finger double-tap screen - - two-finger double-tap screen + + %1$d-finger double tap + + Quickly tap the screen twice with %1$d fingers + + Triple tap + + Quickly tap the screen %1$d times. This may slow down your device. + + %1$d-finger double tap Quickly tap screen {0,number,integer} times with two fingers Triple-tap screen - triple-tap screen + triple tap Quickly tap screen {0,number,integer} times. This shortcut may slow down your device diff --git a/res/xml/accessibility_edit_shortcuts.xml b/res/xml/accessibility_edit_shortcuts.xml index 37e25af96a8..bb555271864 100644 --- a/res/xml/accessibility_edit_shortcuts.xml +++ b/res/xml/accessibility_edit_shortcuts.xml @@ -24,7 +24,7 @@ android:selectable="false" settings:allowDividerAbove="false" settings:allowDividerBelow="false"/> - + + \ No newline at end of file diff --git a/src/com/android/settings/accessibility/AccessibilityGestureNavigationTutorial.java b/src/com/android/settings/accessibility/AccessibilityGestureNavigationTutorial.java index 4b394a0f569..3bb03de9a9c 100644 --- a/src/com/android/settings/accessibility/AccessibilityGestureNavigationTutorial.java +++ b/src/com/android/settings/accessibility/AccessibilityGestureNavigationTutorial.java @@ -29,12 +29,14 @@ import android.text.Spannable; import android.text.SpannableString; import android.text.SpannableStringBuilder; import android.text.style.ImageSpan; +import android.util.ArrayMap; import android.util.Log; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.Window; +import android.widget.Button; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; @@ -57,6 +59,7 @@ import androidx.viewpager.widget.ViewPager; import com.android.server.accessibility.Flags; import com.android.settings.R; import com.android.settings.core.SubSettingLauncher; +import com.android.settingslib.utils.StringUtil; import com.android.settingslib.widget.LottieColorUtils; import com.airbnb.lottie.LottieAnimationView; @@ -66,6 +69,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.List; +import java.util.Map; /** * Utility class for creating the dialog that guides users for gesture navigation for @@ -117,12 +121,17 @@ public final class AccessibilityGestureNavigationTutorial { return createDialog(context, DialogType.LAUNCH_SERVICE_BY_ACCESSIBILITY_GESTURE); } - static AlertDialog createAccessibilityTutorialDialog(Context context, int shortcutTypes) { - return createAccessibilityTutorialDialog(context, shortcutTypes, mOnClickListener); + static AlertDialog createAccessibilityTutorialDialog( + @NonNull Context context, int shortcutTypes, @NonNull CharSequence featureName) { + return createAccessibilityTutorialDialog( + context, shortcutTypes, mOnClickListener, featureName); } - static AlertDialog createAccessibilityTutorialDialog(Context context, int shortcutTypes, - @Nullable DialogInterface.OnClickListener actionButtonListener) { + static AlertDialog createAccessibilityTutorialDialog( + @NonNull Context context, + int shortcutTypes, + @Nullable DialogInterface.OnClickListener actionButtonListener, + @NonNull CharSequence featureName) { final int category = SettingsEnums.SWITCH_SHORTCUT_DIALOG_ACCESSIBILITY_BUTTON_SETTINGS; final DialogInterface.OnClickListener linkButtonListener = @@ -138,46 +147,59 @@ public final class AccessibilityGestureNavigationTutorial { linkButtonListener) .create(); - final List tutorialPages = - createShortcutTutorialPages(context, shortcutTypes); + final List tutorialPages = createShortcutTutorialPages( + context, shortcutTypes, featureName, /* isInSetupWizard= */ false); Preconditions.checkArgument(!tutorialPages.isEmpty(), /* errorMessage= */ "Unexpected tutorial pages size"); - final TutorialPageChangeListener.OnPageSelectedCallback callback = index -> { - final int pageType = tutorialPages.get(index).getType(); - alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE).setVisibility( - pageType == UserShortcutType.SOFTWARE ? VISIBLE : GONE); - }; + final TutorialPageChangeListener.OnPageSelectedCallback callback = + index -> updateTutorialNegativeButtonTextAndVisibility( + alertDialog, tutorialPages, index); alertDialog.setView(createShortcutNavigationContentView(context, tutorialPages, callback)); // Showing first page won't invoke onPageSelectedCallback. Need to check the first tutorial // page type manually to set correct visibility of the link button. - alertDialog.setOnShowListener(dialog -> { - final int firstPageType = tutorialPages.get(0).getType(); - alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE).setVisibility( - firstPageType == UserShortcutType.SOFTWARE ? VISIBLE : GONE); - }); + alertDialog.setOnShowListener( + dialog -> updateTutorialNegativeButtonTextAndVisibility( + alertDialog, tutorialPages, /* selectedPageIndex= */ 0)); return alertDialog; } - static AlertDialog createAccessibilityTutorialDialogForSetupWizard(Context context, - int shortcutTypes) { - return createAccessibilityTutorialDialogForSetupWizard(context, shortcutTypes, - mOnClickListener); + private static void updateTutorialNegativeButtonTextAndVisibility( + AlertDialog dialog, List pages, int selectedPageIndex) { + final Button button = dialog.getButton(DialogInterface.BUTTON_NEGATIVE); + final int pageType = pages.get(selectedPageIndex).getType(); + final int buttonVisibility = pageType == UserShortcutType.SOFTWARE ? VISIBLE : GONE; + button.setVisibility(buttonVisibility); + if (buttonVisibility == VISIBLE) { + final int textResId = AccessibilityUtil.isFloatingMenuEnabled(dialog.getContext()) + ? R.string.accessibility_tutorial_dialog_link_button + : R.string.accessibility_tutorial_dialog_configure_software_shortcut_type; + button.setText(textResId); + } } static AlertDialog createAccessibilityTutorialDialogForSetupWizard(Context context, - int shortcutTypes, @Nullable DialogInterface.OnClickListener actionButtonListener) { + int shortcutTypes, CharSequence featureName) { + return createAccessibilityTutorialDialogForSetupWizard(context, shortcutTypes, + mOnClickListener, featureName); + } + + static AlertDialog createAccessibilityTutorialDialogForSetupWizard( + @NonNull Context context, + int shortcutTypes, + @Nullable DialogInterface.OnClickListener actionButtonListener, + @NonNull CharSequence featureName) { final AlertDialog alertDialog = new AlertDialog.Builder(context) .setPositiveButton(R.string.accessibility_tutorial_dialog_button, actionButtonListener) .create(); - final List tutorialPages = - createShortcutTutorialPages(context, shortcutTypes); + final List tutorialPages = createShortcutTutorialPages( + context, shortcutTypes, featureName, /* inSetupWizard= */ true); Preconditions.checkArgument(!tutorialPages.isEmpty(), /* errorMessage= */ "Unexpected tutorial pages size"); @@ -403,8 +425,8 @@ public final class AccessibilityGestureNavigationTutorial { final View image = createIllustrationViewWithImageRawResource(context, R.raw.a11y_shortcut_type_triple_tap); - final CharSequence instruction = - context.getText(R.string.accessibility_tutorial_dialog_message_triple); + final CharSequence instruction = context.getString( + R.string.accessibility_tutorial_dialog_tripletap_instruction, 3); final ImageView indicatorIcon = createImageView(context, R.drawable.ic_accessibility_page_indicator); indicatorIcon.setEnabled(false); @@ -413,15 +435,16 @@ public final class AccessibilityGestureNavigationTutorial { } private static TutorialPage createTwoFingerTripleTapTutorialPage(@NonNull Context context) { - // TODO(b/308088945): Update tutorial string and image when UX provides them final int type = UserShortcutType.TWOFINGER_DOUBLETAP; - final CharSequence title = - context.getText(R.string.accessibility_tutorial_dialog_title_two_finger_double); + final int numFingers = 2; + final CharSequence title = context.getString( + R.string.accessibility_tutorial_dialog_title_two_finger_double, numFingers); + // TODO(b/308088945): Update tutorial image when UX provides them final View image = createIllustrationViewWithImageRawResource(context, R.raw.a11y_shortcut_type_triple_tap); - final CharSequence instruction = - context.getText(R.string.accessibility_tutorial_dialog_message_two_finger_triple); + final CharSequence instruction = context.getString( + R.string.accessibility_tutorial_dialog_twofinger_doubletap_instruction, numFingers); final ImageView indicatorIcon = createImageView(context, R.drawable.ic_accessibility_page_indicator); indicatorIcon.setEnabled(false); @@ -429,30 +452,50 @@ public final class AccessibilityGestureNavigationTutorial { return new TutorialPage(type, title, image, indicatorIcon, instruction); } - private static TutorialPage createQuickSettingTutorialPage(@NonNull Context context) { + private static TutorialPage createQuickSettingsTutorialPage( + @NonNull Context context, @NonNull CharSequence featureName, boolean inSetupWizard) { final int type = UserShortcutType.QUICK_SETTINGS; final CharSequence title = context.getText(R.string.accessibility_tutorial_dialog_title_quick_setting); final View image = createIllustrationView(context, R.drawable.a11y_shortcut_type_quick_settings); - final CharSequence instruction = - context.getText(R.string.accessibility_tutorial_dialog_message_quick_setting); + final int numFingers = AccessibilityUtil.isTouchExploreEnabled(context) ? 2 : 1; + Map arguments = new ArrayMap<>(); + arguments.put("count", numFingers); + arguments.put("featureName", featureName); + final CharSequence instruction = StringUtil.getIcuPluralsString(context, + arguments, + R.string.accessibility_tutorial_dialog_message_quick_setting); + final SpannableStringBuilder tutorialText = new SpannableStringBuilder(); + if (inSetupWizard) { + tutorialText.append(context.getText( + R.string.accessibility_tutorial_dialog_shortcut_unavailable_in_suw)) + .append("\n\n"); + } + tutorialText.append(instruction); final ImageView indicatorIcon = createImageView(context, R.drawable.ic_accessibility_page_indicator); indicatorIcon.setEnabled(false); - return new TutorialPage(type, title, image, indicatorIcon, instruction); + return new TutorialPage(type, title, image, indicatorIcon, tutorialText); } + /** + * Create the tutorial pages for selected shortcut types in the same order as shown in the + * edit shortcut screen. + */ @VisibleForTesting - static List createShortcutTutorialPages(@NonNull Context context, - int shortcutTypes) { + static List createShortcutTutorialPages( + @NonNull Context context, int shortcutTypes, @NonNull CharSequence featureName, + boolean inSetupWizard) { + // LINT.IfChange(shortcut_type_ui_order) final List tutorialPages = new ArrayList<>(); if (android.view.accessibility.Flags.a11yQsShortcut()) { if ((shortcutTypes & UserShortcutType.QUICK_SETTINGS) == UserShortcutType.QUICK_SETTINGS) { - tutorialPages.add(createQuickSettingTutorialPage(context)); + tutorialPages.add( + createQuickSettingsTutorialPage(context, featureName, inSetupWizard)); } } if ((shortcutTypes & UserShortcutType.SOFTWARE) == UserShortcutType.SOFTWARE) { @@ -463,10 +506,6 @@ public final class AccessibilityGestureNavigationTutorial { tutorialPages.add(createHardwareTutorialPage(context)); } - if ((shortcutTypes & UserShortcutType.TRIPLETAP) == UserShortcutType.TRIPLETAP) { - tutorialPages.add(createTripleTapTutorialPage(context)); - } - if (Flags.enableMagnificationMultipleFingerMultipleTapGesture()) { if ((shortcutTypes & UserShortcutType.TWOFINGER_DOUBLETAP) == UserShortcutType.TWOFINGER_DOUBLETAP) { @@ -474,6 +513,11 @@ public final class AccessibilityGestureNavigationTutorial { } } + if ((shortcutTypes & UserShortcutType.TRIPLETAP) == UserShortcutType.TRIPLETAP) { + tutorialPages.add(createTripleTapTutorialPage(context)); + } + // LINT.ThenChange(/res/xml/accessibility_edit_shortcuts.xml:shortcut_type_ui_order) + return tutorialPages; } @@ -509,10 +553,11 @@ public final class AccessibilityGestureNavigationTutorial { final int resId = R.string.accessibility_tutorial_dialog_message_floating_button; sb.append(context.getText(resId)); } else if (AccessibilityUtil.isGestureNavigateEnabled(context)) { - final int resId = AccessibilityUtil.isTouchExploreEnabled(context) - ? R.string.accessibility_tutorial_dialog_message_gesture_talkback - : R.string.accessibility_tutorial_dialog_message_gesture; - sb.append(context.getText(resId)); + final int numFingers = AccessibilityUtil.isTouchExploreEnabled(context) ? 3 : 2; + sb.append(StringUtil.getIcuPluralsString( + context, + numFingers, + R.string.accessibility_tutorial_dialog_gesture_shortcut_instruction)); } else { final int resId = R.string.accessibility_tutorial_dialog_message_button; sb.append(getSoftwareInstructionWithIcon(context, context.getText(resId))); diff --git a/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java b/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java index 41c5d750b69..603ff7a5ea2 100644 --- a/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java +++ b/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceFragment.java @@ -223,12 +223,12 @@ public abstract class AccessibilityShortcutPreferenceFragment extends Restricted mDialog = AccessibilityGestureNavigationTutorial .createAccessibilityTutorialDialogForSetupWizard( getPrefContext(), getUserShortcutTypes(), - this::callOnTutorialDialogButtonClicked); + this::callOnTutorialDialogButtonClicked, getLabelName()); } else { mDialog = AccessibilityGestureNavigationTutorial .createAccessibilityTutorialDialog( getPrefContext(), getUserShortcutTypes(), - this::callOnTutorialDialogButtonClicked); + this::callOnTutorialDialogButtonClicked, getLabelName()); } mDialog.setCanceledOnTouchOutside(false); return mDialog; @@ -454,6 +454,7 @@ public abstract class AccessibilityShortcutPreferenceFragment extends Restricted final int shortcutTypes = PreferredShortcuts.retrieveUserShortcutType(context, getComponentName().flattenToString()); + // LINT.IfChange(shortcut_type_ui_order) final List list = new ArrayList<>(); if (android.view.accessibility.Flags.a11yQsShortcut()) { if (hasShortcutType(shortcutTypes, AccessibilityUtil.UserShortcutType.QUICK_SETTINGS)) { @@ -470,6 +471,7 @@ public abstract class AccessibilityShortcutPreferenceFragment extends Restricted R.string.accessibility_shortcut_hardware_keyword); list.add(hardwareTitle); } + // LINT.ThenChange(/res/xml/accessibility_edit_shortcuts.xml:shortcut_type_ui_order) // Show software shortcut if first time to use. if (list.isEmpty()) { diff --git a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java index ef828dbf973..a7fce6f2b02 100644 --- a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java @@ -228,12 +228,12 @@ public abstract class ToggleFeaturePreferenceFragment extends DashboardFragment mDialog = AccessibilityGestureNavigationTutorial .createAccessibilityTutorialDialogForSetupWizard( getPrefContext(), getUserShortcutTypes(), - this::callOnTutorialDialogButtonClicked); + this::callOnTutorialDialogButtonClicked, mPackageName); } else { mDialog = AccessibilityGestureNavigationTutorial .createAccessibilityTutorialDialog( getPrefContext(), getUserShortcutTypes(), - this::callOnTutorialDialogButtonClicked); + this::callOnTutorialDialogButtonClicked, mPackageName); } mDialog.setCanceledOnTouchOutside(false); return mDialog; @@ -711,6 +711,7 @@ public abstract class ToggleFeaturePreferenceFragment extends DashboardFragment return context.getText(R.string.accessibility_shortcut_state_off); } + // LINT.IfChange(shortcut_type_ui_order) final int shortcutTypes = PreferredShortcuts.retrieveUserShortcutType( context, mComponentName.flattenToString(), getDefaultShortcutTypes()); @@ -730,6 +731,7 @@ public abstract class ToggleFeaturePreferenceFragment extends DashboardFragment R.string.accessibility_shortcut_hardware_keyword); list.add(hardwareTitle); } + // LINT.ThenChange(/res/xml/accessibility_edit_shortcuts.xml:shortcut_type_ui_order) // Show software shortcut if first time to use. if (list.isEmpty()) { diff --git a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java index 6ef764edfaf..0da55af85d8 100644 --- a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java @@ -484,6 +484,7 @@ public class ToggleScreenMagnificationPreferenceFragment extends final int shortcutTypes = PreferredShortcuts.retrieveUserShortcutType(context, MAGNIFICATION_CONTROLLER_NAME); + // LINT.IfChange(shortcut_type_ui_order) final List list = new ArrayList<>(); if (android.view.accessibility.Flags.a11yQsShortcut()) { if (hasShortcutType(shortcutTypes, UserShortcutType.QUICK_SETTINGS)) { @@ -500,18 +501,19 @@ public class ToggleScreenMagnificationPreferenceFragment extends R.string.accessibility_shortcut_hardware_keyword); list.add(hardwareTitle); } + if (Flags.enableMagnificationMultipleFingerMultipleTapGesture()) { + if (hasShortcutType(shortcutTypes, UserShortcutType.TWOFINGER_DOUBLETAP)) { + final CharSequence twoFingerDoubleTapTitle = context.getString( + R.string.accessibility_shortcut_two_finger_double_tap_keyword, 2); + list.add(twoFingerDoubleTapTitle); + } + } if (hasShortcutType(shortcutTypes, UserShortcutType.TRIPLETAP)) { final CharSequence tripleTapTitle = context.getText( R.string.accessibility_shortcut_triple_tap_keyword); list.add(tripleTapTitle); } - if (Flags.enableMagnificationMultipleFingerMultipleTapGesture()) { - if (hasShortcutType(shortcutTypes, UserShortcutType.TWOFINGER_DOUBLETAP)) { - final CharSequence twoFingerTripleTapTitle = context.getText( - R.string.accessibility_shortcut_two_finger_double_tap_keyword); - list.add(twoFingerTripleTapTitle); - } - } + // LINT.ThenChange(/res/xml/accessibility_edit_shortcuts.xml:shortcut_type_ui_order) // Show software shortcut if first time to use. if (list.isEmpty()) { diff --git a/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragment.java b/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragment.java index 976fffb2aca..036190b8e19 100644 --- a/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragment.java +++ b/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragment.java @@ -258,8 +258,10 @@ public class EditShortcutsPreferenceFragment extends DashboardFragment { @Override public void onResume() { super.onResume(); - mTouchExplorationStateChangeListener = isTouchExplorationEnabled -> - refreshPreferenceController(GestureShortcutOptionController.class); + mTouchExplorationStateChangeListener = isTouchExplorationEnabled -> { + refreshPreferenceController(QuickSettingsShortcutOptionController.class); + refreshPreferenceController(GestureShortcutOptionController.class); + }; final AccessibilityManager am = getSystemService( AccessibilityManager.class); diff --git a/src/com/android/settings/accessibility/shortcuts/FloatingButtonShortcutOptionController.java b/src/com/android/settings/accessibility/shortcuts/FloatingButtonShortcutOptionController.java index e72a85d9cae..f3c427a4f20 100644 --- a/src/com/android/settings/accessibility/shortcuts/FloatingButtonShortcutOptionController.java +++ b/src/com/android/settings/accessibility/shortcuts/FloatingButtonShortcutOptionController.java @@ -57,9 +57,12 @@ public class FloatingButtonShortcutOptionController @Nullable @Override public CharSequence getSummary() { - if (isInSetupWizard()) { - return null; + final SpannableStringBuilder sb = new SpannableStringBuilder(); + sb.append(mContext.getText( + R.string.accessibility_shortcut_edit_dialog_summary_floating_button)); + if (!isInSetupWizard()) { + sb.append("\n\n").append(getCustomizeAccessibilityButtonLink()); } - return new SpannableStringBuilder().append(getCustomizeAccessibilityButtonLink()); + return sb; } } diff --git a/src/com/android/settings/accessibility/shortcuts/GestureShortcutOptionController.java b/src/com/android/settings/accessibility/shortcuts/GestureShortcutOptionController.java index fb312c66293..7ea30b6a0ff 100644 --- a/src/com/android/settings/accessibility/shortcuts/GestureShortcutOptionController.java +++ b/src/com/android/settings/accessibility/shortcuts/GestureShortcutOptionController.java @@ -24,6 +24,7 @@ import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.accessibility.AccessibilityUtil; +import com.android.settingslib.utils.StringUtil; /** * A controller handles displaying the gesture shortcut option preference and @@ -59,13 +60,18 @@ public class GestureShortcutOptionController extends SoftwareShortcutOptionPrefe @Override public CharSequence getSummary() { + int numFingers = AccessibilityUtil.isTouchExploreEnabled(mContext) ? 3 : 2; + String instruction = StringUtil.getIcuPluralsString( + mContext, + numFingers, + R.string.accessibility_shortcut_edit_dialog_summary_gesture); + final SpannableStringBuilder sb = new SpannableStringBuilder(); - final int resId = AccessibilityUtil.isTouchExploreEnabled(mContext) - ? R.string.accessibility_shortcut_edit_dialog_summary_software_gesture_talkback - : R.string.accessibility_shortcut_edit_dialog_summary_software_gesture; - sb.append(mContext.getText(resId)); - sb.append("\n\n"); - sb.append(getCustomizeAccessibilityButtonLink()); + sb.append(instruction); + if (!isInSetupWizard()) { + sb.append("\n\n"); + sb.append(getCustomizeAccessibilityButtonLink()); + } return sb; } diff --git a/src/com/android/settings/accessibility/shortcuts/QuickSettingsShortcutOptionController.java b/src/com/android/settings/accessibility/shortcuts/QuickSettingsShortcutOptionController.java index 27f6bc9d281..f96e1b02b80 100644 --- a/src/com/android/settings/accessibility/shortcuts/QuickSettingsShortcutOptionController.java +++ b/src/com/android/settings/accessibility/shortcuts/QuickSettingsShortcutOptionController.java @@ -34,6 +34,8 @@ import androidx.preference.PreferenceScreen; import com.android.internal.accessibility.common.ShortcutConstants; import com.android.internal.accessibility.util.AccessibilityUtils; import com.android.settings.R; +import com.android.settings.accessibility.AccessibilityUtil; +import com.android.settingslib.utils.StringUtil; import java.util.List; import java.util.Map; @@ -62,13 +64,22 @@ public class QuickSettingsShortcutOptionController extends ShortcutOptionPrefere if (preference instanceof ShortcutOptionPreference shortcutOptionPreference) { shortcutOptionPreference.setTitle( R.string.accessibility_shortcut_edit_dialog_title_quick_settings); - shortcutOptionPreference.setSummary( - R.string.accessibility_shortcut_edit_dialog_summary_quick_settings); shortcutOptionPreference.setIntroImageResId( R.drawable.a11y_shortcut_type_quick_settings); } } + @Override + public CharSequence getSummary() { + int numFingers = AccessibilityUtil.isTouchExploreEnabled(mContext) ? 2 : 1; + return StringUtil.getIcuPluralsString( + mContext, + numFingers, + isInSetupWizard() + ? R.string.accessibility_shortcut_edit_dialog_summary_quick_settings_suw + : R.string.accessibility_shortcut_edit_dialog_summary_quick_settings); + } + @Override protected boolean isShortcutAvailable() { return Flags.a11yQsShortcut() @@ -91,7 +102,8 @@ public class QuickSettingsShortcutOptionController extends ShortcutOptionPrefere } for (String target : getShortcutTargets()) { ComponentName targetComponentName = ComponentName.unflattenFromString(target); - if (!a11yFeatureToTileMap.containsKey(targetComponentName)) { + if (targetComponentName == null + || !a11yFeatureToTileMap.containsKey(targetComponentName)) { return false; } } diff --git a/src/com/android/settings/accessibility/shortcuts/TripleTapShortcutOptionController.java b/src/com/android/settings/accessibility/shortcuts/TripleTapShortcutOptionController.java index e43aeb29b5d..a4cc70bc2e4 100644 --- a/src/com/android/settings/accessibility/shortcuts/TripleTapShortcutOptionController.java +++ b/src/com/android/settings/accessibility/shortcuts/TripleTapShortcutOptionController.java @@ -19,7 +19,6 @@ package com.android.settings.accessibility.shortcuts; import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME; import android.content.Context; -import android.icu.text.MessageFormat; import android.provider.Settings; import android.view.accessibility.Flags; @@ -52,12 +51,9 @@ public class TripleTapShortcutOptionController extends ShortcutOptionPreferenceC final Preference preference = screen.findPreference(getPreferenceKey()); if (preference instanceof ShortcutOptionPreference shortcutOptionPreference) { shortcutOptionPreference.setTitle( - R.string.accessibility_shortcut_edit_dialog_title_triple_tap); + R.string.accessibility_shortcut_edit_screen_title_triple_tap); String summary = mContext.getString( - R.string.accessibility_shortcut_edit_dialog_summary_triple_tap); - // Format the number '3' in the summary. - final Object[] arguments = {3}; - summary = MessageFormat.format(summary, arguments); + R.string.accessibility_shortcut_edit_screen_summary_triple_tap, 3); shortcutOptionPreference.setSummary(summary); shortcutOptionPreference.setIntroImageRawResId( diff --git a/src/com/android/settings/accessibility/shortcuts/TwoFingerDoubleTapShortcutOptionController.java b/src/com/android/settings/accessibility/shortcuts/TwoFingerDoubleTapShortcutOptionController.java index 83ba6e4e9b9..0fc9f8e9508 100644 --- a/src/com/android/settings/accessibility/shortcuts/TwoFingerDoubleTapShortcutOptionController.java +++ b/src/com/android/settings/accessibility/shortcuts/TwoFingerDoubleTapShortcutOptionController.java @@ -19,7 +19,6 @@ package com.android.settings.accessibility.shortcuts; import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME; import android.content.Context; -import android.icu.text.MessageFormat; import android.provider.Settings; import androidx.preference.Preference; @@ -54,16 +53,17 @@ public class TwoFingerDoubleTapShortcutOptionController super.displayPreference(screen); final Preference preference = screen.findPreference(getPreferenceKey()); if (preference instanceof ShortcutOptionPreference shortcutOptionPreference) { - // TODO (b/306153204): Update shortcut string and image when UX provides them - shortcutOptionPreference.setTitle( - R.string.accessibility_shortcut_edit_dialog_title_two_finger_double_tap); + int numFingers = 2; + String title = mContext.getString( + R.string.accessibility_shortcut_edit_screen_title_two_finger_double_tap, + numFingers); + shortcutOptionPreference.setTitle(title); String summary = mContext.getString( - R.string.accessibility_shortcut_edit_dialog_summary_two_finger_double_tap); - // Format the number '2' in the summary. - final Object[] arguments = {2}; - summary = MessageFormat.format(summary, arguments); + R.string.accessibility_shortcut_edit_screen_summary_two_finger_double_tap, + numFingers); shortcutOptionPreference.setSummary(summary); + // TODO (b/306153204): Update shortcut image when UX provides them shortcutOptionPreference.setIntroImageRawResId( R.raw.a11y_shortcut_type_triple_tap); } diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityGestureNavigationTutorialTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityGestureNavigationTutorialTest.java index edefec2c6cb..18a3c3abaac 100644 --- a/tests/robotests/src/com/android/settings/accessibility/AccessibilityGestureNavigationTutorialTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityGestureNavigationTutorialTest.java @@ -32,18 +32,27 @@ import android.app.settings.SettingsEnums; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; -import android.platform.test.annotations.RequiresFlagsEnabled; -import android.platform.test.flag.junit.CheckFlagsRule; -import android.platform.test.flag.junit.DeviceFlagsValueProvider; +import android.platform.test.annotations.EnableFlags; +import android.platform.test.flag.junit.SetFlagsRule; +import android.text.SpannableStringBuilder; +import android.util.ArrayMap; import android.view.View; +import android.view.accessibility.AccessibilityManager; +import android.widget.Button; +import android.widget.TextSwitcher; +import android.widget.TextView; import androidx.appcompat.app.AlertDialog; import androidx.test.core.app.ApplicationProvider; import com.android.server.accessibility.Flags; +import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.SubSettings; +import com.android.settings.testutils.AccessibilityTestUtils; +import com.android.settings.testutils.shadow.SettingsShadowResources; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; +import com.android.settingslib.utils.StringUtil; import org.junit.Before; import org.junit.Rule; @@ -54,16 +63,22 @@ import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import org.robolectric.Robolectric; import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowAccessibilityManager; import org.robolectric.shadows.ShadowLooper; +import java.util.Map; + /** Tests for {@link AccessibilityGestureNavigationTutorial}. */ +@Config(shadows = SettingsShadowResources.class) @RunWith(RobolectricTestRunner.class) public final class AccessibilityGestureNavigationTutorialTest { + private static final String FAKE_FEATURE_NAME = "Fake Feature Name"; @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); @Rule - public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); + public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @Mock private DialogInterface.OnClickListener mOnClickListener; @Mock @@ -79,7 +94,7 @@ public final class AccessibilityGestureNavigationTutorialTest { @Test(expected = IllegalArgumentException.class) public void createTutorialPages_shortcutListIsEmpty_throwsException() { - createAccessibilityTutorialDialog(mContext, mShortcutTypes); + createAccessibilityTutorialDialog(mContext, mShortcutTypes, FAKE_FEATURE_NAME); } @Test @@ -87,36 +102,42 @@ public final class AccessibilityGestureNavigationTutorialTest { mShortcutTypes |= UserShortcutType.TRIPLETAP; final AlertDialog alertDialog = - createAccessibilityTutorialDialog(mContext, mShortcutTypes); + createAccessibilityTutorialDialog(mContext, mShortcutTypes, FAKE_FEATURE_NAME); - assertThat(createShortcutTutorialPages(mContext, - mShortcutTypes)).hasSize(/* expectedSize= */ 1); + assertThat( + createShortcutTutorialPages( + mContext, mShortcutTypes, FAKE_FEATURE_NAME, /* inSetupWizard= */ false) + ).hasSize(/* expectedSize= */ 1); assertThat(alertDialog).isNotNull(); } @Test - @RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE) + @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE) public void createTutorialPages_turnOnTwoFingerTripleTapShortcut_hasOnePage() { mShortcutTypes |= UserShortcutType.TWOFINGER_DOUBLETAP; final AlertDialog alertDialog = - createAccessibilityTutorialDialog(mContext, mShortcutTypes); + createAccessibilityTutorialDialog(mContext, mShortcutTypes, FAKE_FEATURE_NAME); - assertThat(createShortcutTutorialPages(mContext, - mShortcutTypes)).hasSize(/* expectedSize= */ 1); + assertThat( + createShortcutTutorialPages( + mContext, mShortcutTypes, FAKE_FEATURE_NAME, /* inSetupWizard= */ false) + ).hasSize(/* expectedSize= */ 1); assertThat(alertDialog).isNotNull(); } @Test - @RequiresFlagsEnabled(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) + @EnableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) public void createTutorialPages_turnOnQuickSettingShortcut_hasOnePage() { mShortcutTypes |= UserShortcutType.QUICK_SETTINGS; final AlertDialog alertDialog = - createAccessibilityTutorialDialog(mContext, mShortcutTypes); + createAccessibilityTutorialDialog(mContext, mShortcutTypes, FAKE_FEATURE_NAME); - assertThat(createShortcutTutorialPages(mContext, - mShortcutTypes)).hasSize(/* expectedSize= */ 1); + assertThat( + createShortcutTutorialPages( + mContext, mShortcutTypes, FAKE_FEATURE_NAME, /* inSetupWizard= */ false) + ).hasSize(/* expectedSize= */ 1); assertThat(alertDialog).isNotNull(); } @@ -125,10 +146,12 @@ public final class AccessibilityGestureNavigationTutorialTest { mShortcutTypes |= UserShortcutType.SOFTWARE; final AlertDialog alertDialog = - createAccessibilityTutorialDialog(mContext, mShortcutTypes); + createAccessibilityTutorialDialog(mContext, mShortcutTypes, FAKE_FEATURE_NAME); - assertThat(createShortcutTutorialPages(mContext, - mShortcutTypes)).hasSize(/* expectedSize= */ 1); + assertThat( + createShortcutTutorialPages( + mContext, mShortcutTypes, FAKE_FEATURE_NAME, /* inSetupWizard= */ false) + ).hasSize(/* expectedSize= */ 1); assertThat(alertDialog).isNotNull(); } @@ -138,36 +161,69 @@ public final class AccessibilityGestureNavigationTutorialTest { mShortcutTypes |= UserShortcutType.HARDWARE; final AlertDialog alertDialog = - createAccessibilityTutorialDialog(mContext, mShortcutTypes); + createAccessibilityTutorialDialog(mContext, mShortcutTypes, FAKE_FEATURE_NAME); - assertThat(createShortcutTutorialPages(mContext, - mShortcutTypes)).hasSize(/* expectedSize= */ 2); + assertThat( + createShortcutTutorialPages( + mContext, mShortcutTypes, FAKE_FEATURE_NAME, /* inSetupWizard= */ false) + ).hasSize(/* expectedSize= */ 2); assertThat(alertDialog).isNotNull(); } @Test - public void createTutorialPages_turnOnSoftwareShortcut_linkButtonVisible() { + public void createTutorialPages_turnOnA11yGestureShortcut_linkButtonShownWithText() { mShortcutTypes |= UserShortcutType.SOFTWARE; + AccessibilityTestUtils.setSoftwareShortcutMode( + mContext, /* gestureNavEnabled= */ true, /* floatingButtonEnabled= */ false); final AlertDialog alertDialog = - createAccessibilityTutorialDialog(mContext, mShortcutTypes); + createAccessibilityTutorialDialog(mContext, mShortcutTypes, FAKE_FEATURE_NAME); alertDialog.show(); + ShadowLooper.idleMainLooper(); - assertThat(alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE).getVisibility()) - .isEqualTo(View.VISIBLE); + Button btn = alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE); + assertThat(btn).isNotNull(); + assertThat(btn.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(btn.getText().toString()).isEqualTo( + mContext.getString( + R.string.accessibility_tutorial_dialog_configure_software_shortcut_type)); } @Test - public void createTutorialPages_turnOnSoftwareAndHardwareShortcut_linkButtonVisible() { + public void createTutorialPages_turnOnA11yNavButtonShortcut_linkButtonShownWithText() { mShortcutTypes |= UserShortcutType.SOFTWARE; - mShortcutTypes |= UserShortcutType.HARDWARE; + AccessibilityTestUtils.setSoftwareShortcutMode( + mContext, /* gestureNavEnabled= */ false, /* floatingButtonEnabled= */ false); final AlertDialog alertDialog = - createAccessibilityTutorialDialog(mContext, mShortcutTypes); + createAccessibilityTutorialDialog(mContext, mShortcutTypes, FAKE_FEATURE_NAME); alertDialog.show(); + ShadowLooper.idleMainLooper(); - assertThat(alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE).getVisibility()) - .isEqualTo(View.VISIBLE); + Button btn = alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE); + assertThat(btn).isNotNull(); + assertThat(btn.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(btn.getText().toString()).isEqualTo( + mContext.getString( + R.string.accessibility_tutorial_dialog_configure_software_shortcut_type)); + } + + @Test + public void createTutorialPages_turnOnFloatingButtonShortcut_linkButtonShownWithText() { + mShortcutTypes |= UserShortcutType.SOFTWARE; + AccessibilityTestUtils.setSoftwareShortcutMode( + mContext, /* gestureNavEnabled= */ false, /* floatingButtonEnabled= */ true); + + final AlertDialog alertDialog = + createAccessibilityTutorialDialog(mContext, mShortcutTypes, FAKE_FEATURE_NAME); + alertDialog.show(); + ShadowLooper.idleMainLooper(); + + Button btn = alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE); + assertThat(btn).isNotNull(); + assertThat(btn.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(btn.getText().toString()).isEqualTo( + mContext.getString(R.string.accessibility_tutorial_dialog_link_button)); } @Test @@ -175,7 +231,7 @@ public final class AccessibilityGestureNavigationTutorialTest { mShortcutTypes |= UserShortcutType.HARDWARE; final AlertDialog alertDialog = - createAccessibilityTutorialDialog(mContext, mShortcutTypes); + createAccessibilityTutorialDialog(mContext, mShortcutTypes, FAKE_FEATURE_NAME); alertDialog.show(); ShadowLooper.idleMainLooper(); @@ -188,20 +244,293 @@ public final class AccessibilityGestureNavigationTutorialTest { mShortcutTypes |= UserShortcutType.SOFTWARE; final AlertDialog alertDialog = - createAccessibilityTutorialDialogForSetupWizard(mContext, mShortcutTypes); + createAccessibilityTutorialDialogForSetupWizard( + mContext, mShortcutTypes, FAKE_FEATURE_NAME); alertDialog.show(); + ShadowLooper.idleMainLooper(); assertThat(alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE).getVisibility()) .isEqualTo(View.GONE); } + @Test + @EnableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) + public void createAccessibilityTutorialDialog_qsShortcut_inSuwTalkbackOn_verifyText() { + mShortcutTypes |= UserShortcutType.QUICK_SETTINGS; + setTouchExplorationEnabled(true); + final String expectedTitle = mContext.getString( + R.string.accessibility_tutorial_dialog_title_quick_setting); + Map arguments = new ArrayMap<>(); + arguments.put("count", 2); + arguments.put("featureName", FAKE_FEATURE_NAME); + final CharSequence instruction = StringUtil.getIcuPluralsString(mContext, + arguments, + R.string.accessibility_tutorial_dialog_message_quick_setting); + final SpannableStringBuilder expectedInstruction = new SpannableStringBuilder(); + expectedInstruction + .append(mContext.getText( + R.string.accessibility_tutorial_dialog_shortcut_unavailable_in_suw)) + .append("\n\n"); + expectedInstruction.append(instruction); + + final AlertDialog alertDialog = + createAccessibilityTutorialDialogForSetupWizard( + mContext, mShortcutTypes, FAKE_FEATURE_NAME); + alertDialog.show(); + ShadowLooper.idleMainLooper(); + + verifyTutorialTitleAndInstruction( + alertDialog, + expectedTitle, + expectedInstruction.toString()); + } + + @Test + @EnableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) + public void createAccessibilityTutorialDialog_qsShortcut_notInSuwTalkbackOn_verifyText() { + mShortcutTypes |= UserShortcutType.QUICK_SETTINGS; + setTouchExplorationEnabled(true); + final String expectedTitle = mContext.getString( + R.string.accessibility_tutorial_dialog_title_quick_setting); + Map arguments = new ArrayMap<>(); + arguments.put("count", 2); + arguments.put("featureName", FAKE_FEATURE_NAME); + final CharSequence expectedInstruction = StringUtil.getIcuPluralsString(mContext, + arguments, + R.string.accessibility_tutorial_dialog_message_quick_setting); + + final AlertDialog alertDialog = + createAccessibilityTutorialDialog( + mContext, mShortcutTypes, FAKE_FEATURE_NAME); + alertDialog.show(); + ShadowLooper.idleMainLooper(); + + verifyTutorialTitleAndInstruction( + alertDialog, + expectedTitle, + expectedInstruction.toString()); + } + + @Test + @EnableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) + public void createAccessibilityTutorialDialog_qsShortcut_inSuwTalkbackOff_verifyText() { + mShortcutTypes |= UserShortcutType.QUICK_SETTINGS; + setTouchExplorationEnabled(false); + final String expectedTitle = mContext.getString( + R.string.accessibility_tutorial_dialog_title_quick_setting); + Map arguments = new ArrayMap<>(); + arguments.put("count", 1); + arguments.put("featureName", FAKE_FEATURE_NAME); + final CharSequence instruction = StringUtil.getIcuPluralsString(mContext, + arguments, + R.string.accessibility_tutorial_dialog_message_quick_setting); + final SpannableStringBuilder expectedInstruction = new SpannableStringBuilder(); + expectedInstruction.append(mContext.getText( + R.string.accessibility_tutorial_dialog_shortcut_unavailable_in_suw)) + .append("\n\n"); + expectedInstruction.append(instruction); + + final AlertDialog alertDialog = + createAccessibilityTutorialDialogForSetupWizard( + mContext, mShortcutTypes, FAKE_FEATURE_NAME); + alertDialog.show(); + ShadowLooper.idleMainLooper(); + + verifyTutorialTitleAndInstruction( + alertDialog, + expectedTitle, + expectedInstruction.toString()); + } + + @Test + @EnableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) + public void createAccessibilityTutorialDialog_qsShortcut_notInSuwTalkbackOff_verifyText() { + mShortcutTypes |= UserShortcutType.QUICK_SETTINGS; + setTouchExplorationEnabled(false); + final String expectedTitle = mContext.getString( + R.string.accessibility_tutorial_dialog_title_quick_setting); + Map arguments = new ArrayMap<>(); + arguments.put("count", 1); + arguments.put("featureName", FAKE_FEATURE_NAME); + final CharSequence expectedInstruction = StringUtil.getIcuPluralsString(mContext, + arguments, + R.string.accessibility_tutorial_dialog_message_quick_setting); + + final AlertDialog alertDialog = + createAccessibilityTutorialDialog( + mContext, mShortcutTypes, FAKE_FEATURE_NAME); + alertDialog.show(); + ShadowLooper.idleMainLooper(); + + verifyTutorialTitleAndInstruction( + alertDialog, + expectedTitle, + expectedInstruction.toString()); + } + + @Test + public void createAccessibilityTutorialDialog_volumeKeysShortcut_verifyText() { + mShortcutTypes |= UserShortcutType.HARDWARE; + final String expectedTitle = mContext.getString( + R.string.accessibility_tutorial_dialog_title_volume); + final CharSequence expectedInstruction = mContext.getString( + R.string.accessibility_tutorial_dialog_message_volume); + + final AlertDialog alertDialog = + createAccessibilityTutorialDialog( + mContext, mShortcutTypes, FAKE_FEATURE_NAME); + alertDialog.show(); + ShadowLooper.idleMainLooper(); + + verifyTutorialTitleAndInstruction( + alertDialog, + expectedTitle, + expectedInstruction.toString()); + } + + @Test + public void createAccessibilityTutorialDialog_tripleTapShortcut_verifyText() { + mShortcutTypes |= UserShortcutType.TRIPLETAP; + final String expectedTitle = mContext.getString( + R.string.accessibility_tutorial_dialog_title_triple); + final CharSequence expectedInstruction = mContext.getString( + R.string.accessibility_tutorial_dialog_tripletap_instruction, 3); + + final AlertDialog alertDialog = + createAccessibilityTutorialDialog( + mContext, mShortcutTypes, FAKE_FEATURE_NAME); + alertDialog.show(); + ShadowLooper.idleMainLooper(); + + verifyTutorialTitleAndInstruction( + alertDialog, + expectedTitle, + expectedInstruction.toString()); + } + + @Test + @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE) + public void createAccessibilityTutorialDialog_twoFingerDoubleTapShortcut_verifyText() { + mShortcutTypes |= UserShortcutType.TWOFINGER_DOUBLETAP; + final int numFingers = 2; + final String expectedTitle = mContext.getString( + R.string.accessibility_tutorial_dialog_title_two_finger_double, numFingers); + final String expectedInstruction = mContext.getString( + R.string.accessibility_tutorial_dialog_twofinger_doubletap_instruction, numFingers); + + final AlertDialog alertDialog = + createAccessibilityTutorialDialog( + mContext, mShortcutTypes, FAKE_FEATURE_NAME); + alertDialog.show(); + ShadowLooper.idleMainLooper(); + + verifyTutorialTitleAndInstruction( + alertDialog, + expectedTitle, + expectedInstruction); + } + + @Test + public void createAccessibilityTutorialDialog_floatingButtonShortcut_verifyText() { + mShortcutTypes |= UserShortcutType.SOFTWARE; + AccessibilityTestUtils.setSoftwareShortcutMode( + mContext, /* gestureNavEnabled= */ false, /* floatingButtonEnabled= */ true); + final String expectedTitle = mContext.getString( + R.string.accessibility_tutorial_dialog_title_button); + final String expectedInstruction = mContext.getString( + R.string.accessibility_tutorial_dialog_message_floating_button); + + final AlertDialog alertDialog = + createAccessibilityTutorialDialog( + mContext, mShortcutTypes, FAKE_FEATURE_NAME); + alertDialog.show(); + ShadowLooper.idleMainLooper(); + + verifyTutorialTitleAndInstruction( + alertDialog, + expectedTitle, + expectedInstruction); + } + + @Test + public void createAccessibilityTutorialDialog_navA11yButtonShortcut_verifyText() { + mShortcutTypes |= UserShortcutType.SOFTWARE; + AccessibilityTestUtils.setSoftwareShortcutMode( + mContext, /* gestureNavEnabled= */ false, /* floatingButtonEnabled= */ false); + final String expectedTitle = mContext.getString( + R.string.accessibility_tutorial_dialog_title_button); + final String expectedInstruction = mContext.getString( + R.string.accessibility_tutorial_dialog_message_button); + + final AlertDialog alertDialog = + createAccessibilityTutorialDialog( + mContext, mShortcutTypes, FAKE_FEATURE_NAME); + alertDialog.show(); + ShadowLooper.idleMainLooper(); + + verifyTutorialTitleAndInstruction( + alertDialog, + expectedTitle, + expectedInstruction); + } + + @Test + public void createAccessibilityTutorialDialog_gestureShortcut_talkbackOn_verifyText() { + mShortcutTypes |= UserShortcutType.SOFTWARE; + setTouchExplorationEnabled(true); + AccessibilityTestUtils.setSoftwareShortcutMode( + mContext, /* gestureNavEnabled= */ true, /* floatingButtonEnabled= */ false); + final String expectedTitle = mContext.getString( + R.string.accessibility_tutorial_dialog_title_gesture); + final String expectedInstruction = StringUtil.getIcuPluralsString( + mContext, + /* count= */ 3, + R.string.accessibility_tutorial_dialog_gesture_shortcut_instruction); + + final AlertDialog alertDialog = + createAccessibilityTutorialDialog( + mContext, mShortcutTypes, FAKE_FEATURE_NAME); + alertDialog.show(); + ShadowLooper.idleMainLooper(); + + verifyTutorialTitleAndInstruction( + alertDialog, + expectedTitle, + expectedInstruction); + } + + @Test + public void createAccessibilityTutorialDialog_gestureShortcut_talkbackOff_verifyText() { + mShortcutTypes |= UserShortcutType.SOFTWARE; + setTouchExplorationEnabled(false); + AccessibilityTestUtils.setSoftwareShortcutMode( + mContext, /* gestureNavEnabled= */ true, /* floatingButtonEnabled= */ false); + final String expectedTitle = mContext.getString( + R.string.accessibility_tutorial_dialog_title_gesture); + final String expectedInstruction = StringUtil.getIcuPluralsString( + mContext, + /* count= */ 2, + R.string.accessibility_tutorial_dialog_gesture_shortcut_instruction); + + final AlertDialog alertDialog = + createAccessibilityTutorialDialog( + mContext, mShortcutTypes, FAKE_FEATURE_NAME); + alertDialog.show(); + ShadowLooper.idleMainLooper(); + + verifyTutorialTitleAndInstruction( + alertDialog, + expectedTitle, + expectedInstruction); + } @Test public void performClickOnPositiveButton_turnOnSoftwareShortcut_dismiss() { mShortcutTypes |= UserShortcutType.SOFTWARE; final AlertDialog alertDialog = - createAccessibilityTutorialDialog(mContext, mShortcutTypes); + createAccessibilityTutorialDialog(mContext, mShortcutTypes, FAKE_FEATURE_NAME); alertDialog.show(); + ShadowLooper.idleMainLooper(); alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick(); ShadowLooper.idleMainLooper(); @@ -213,8 +542,10 @@ public final class AccessibilityGestureNavigationTutorialTest { public void performClickOnPositiveButton_turnOnSoftwareShortcut_callOnClickListener() { mShortcutTypes |= UserShortcutType.SOFTWARE; final AlertDialog alertDialog = - createAccessibilityTutorialDialog(mContext, mShortcutTypes, mOnClickListener); + createAccessibilityTutorialDialog( + mContext, mShortcutTypes, mOnClickListener, FAKE_FEATURE_NAME); alertDialog.show(); + ShadowLooper.idleMainLooper(); alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick(); ShadowLooper.idleMainLooper(); @@ -226,7 +557,8 @@ public final class AccessibilityGestureNavigationTutorialTest { public void performClickOnNegativeButton_turnOnSoftwareShortcut_directToSettingsPage() { mShortcutTypes |= UserShortcutType.SOFTWARE; Activity activity = Robolectric.buildActivity(Activity.class).create().get(); - final AlertDialog alertDialog = createAccessibilityTutorialDialog(activity, mShortcutTypes); + final AlertDialog alertDialog = + createAccessibilityTutorialDialog(activity, mShortcutTypes, FAKE_FEATURE_NAME); alertDialog.show(); alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE).performClick(); @@ -251,4 +583,22 @@ public final class AccessibilityGestureNavigationTutorialTest { assertThat(alertDialog.isShowing()).isFalse(); verify(mOnDismissListener).onDismiss(alertDialog); } + + private void setTouchExplorationEnabled(boolean enable) { + ShadowAccessibilityManager am = shadowOf( + mContext.getSystemService(AccessibilityManager.class)); + am.setTouchExplorationEnabled(enable); + } + + private void verifyTutorialTitleAndInstruction(AlertDialog alertDialog, String expectedTitle, + String expectedInstruction) { + TextSwitcher titleView = alertDialog.findViewById(R.id.title); + assertThat(titleView).isNotNull(); + assertThat(((TextView) titleView.getCurrentView()).getText().toString()).isEqualTo( + expectedTitle); + TextSwitcher instructionView = alertDialog.findViewById(R.id.instruction); + assertThat(instructionView).isNotNull(); + assertThat(((TextView) instructionView.getCurrentView()).getText().toString()).isEqualTo( + expectedInstruction); + } } diff --git a/tests/robotests/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragmentTest.java index 526b4318286..b461cab3d04 100644 --- a/tests/robotests/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragmentTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragmentTest.java @@ -16,8 +16,6 @@ package com.android.settings.accessibility.shortcuts; -import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL; - import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_COMPONENT_NAME; import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME; import static com.android.settings.accessibility.shortcuts.EditShortcutsPreferenceFragment.SHORTCUT_SETTINGS; @@ -38,10 +36,12 @@ import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Bundle; +import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; import android.provider.Settings; import android.util.Pair; import android.view.accessibility.AccessibilityManager; +import android.view.accessibility.Flags; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.testing.FragmentScenario; @@ -58,9 +58,11 @@ import com.android.settings.SettingsActivity; import com.android.settings.SubSettings; import com.android.settings.accessibility.AccessibilityUtil; import com.android.settings.accessibility.PreferredShortcuts; +import com.android.settings.testutils.AccessibilityTestUtils; import com.android.settings.testutils.shadow.SettingsShadowResources; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; +import com.android.settingslib.utils.StringUtil; import com.google.android.setupcompat.util.WizardManagerHelper; @@ -72,6 +74,7 @@ import org.junit.runner.RunWith; import org.robolectric.Robolectric; import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; +import org.robolectric.shadow.api.Shadow; import org.robolectric.shadows.ShadowAccessibilityManager; import org.robolectric.shadows.ShadowContentResolver; import org.robolectric.shadows.ShadowLooper; @@ -81,6 +84,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.Set; /** @@ -96,6 +100,8 @@ public class EditShortcutsPreferenceFragmentTest { private static final CharSequence SCREEN_TITLE = "Fake shortcut title"; private static final ComponentName TARGET_FAKE_COMPONENT = new ComponentName("FakePackage", "FakeClass"); + private static final ComponentName TARGET_FAKE_COMPONENT_TILE = + new ComponentName("FakePackage", "FakeTile"); private static final String TARGET = MAGNIFICATION_CONTROLLER_NAME; private static final Set TARGETS = Set.of(TARGET); @@ -109,12 +115,14 @@ public class EditShortcutsPreferenceFragmentTest { @Before public void setUp() { + AccessibilityTestUtils.setSoftwareShortcutMode(mContext, /* gestureNavEnabled= */ + true, /* floatingButtonEnabled= */ false); SettingsShadowResources.overrideResource( - com.android.internal.R.integer.config_navBarInteractionMode, - NAV_BAR_MODE_GESTURAL); - Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.ACCESSIBILITY_BUTTON_MODE, - Settings.Secure.ACCESSIBILITY_BUTTON_MODE_GESTURE); + com.android.internal.R.bool.config_quickSettingsSupported, true); + com.android.settings.testutils.shadow.ShadowAccessibilityManager a11yManager = + Shadow.extract(mContext.getSystemService(AccessibilityManager.class)); + a11yManager.setA11yFeatureToTileMap( + Map.of(TARGET_FAKE_COMPONENT, TARGET_FAKE_COMPONENT_TILE)); mActivity = Robolectric.buildActivity(FragmentActivity.class).get(); } @@ -158,7 +166,7 @@ public class EditShortcutsPreferenceFragmentTest { @Test public void fragmentCreated_inSuw_controllersTargetsSet() { - mFragmentScenario = createFragScenario(/* isInSuw= */ true); + mFragmentScenario = createFragScenario(/* isInSuw= */ true, TARGET); mFragmentScenario.moveToState(Lifecycle.State.CREATED); mFragmentScenario.onFragment(fragment -> { @@ -174,7 +182,7 @@ public class EditShortcutsPreferenceFragmentTest { @Test public void fragmentCreated_notInSuw_controllersTargetsSet() { - mFragmentScenario = createFragScenario(/* isInSuw= */ false); + mFragmentScenario = createFragScenario(/* isInSuw= */ false, TARGET); mFragmentScenario.moveToState(Lifecycle.State.CREATED); mFragmentScenario.onFragment(fragment -> { @@ -195,7 +203,7 @@ public class EditShortcutsPreferenceFragmentTest { assertThat(contentResolver.getContentObservers(uri)).isEmpty(); } - mFragmentScenario = createFragScenario(/* isInSuw= */ false); + mFragmentScenario = createFragScenario(/* isInSuw= */ false, TARGET); mFragmentScenario.moveToState(Lifecycle.State.CREATED); for (Uri uri : SHORTCUT_SETTINGS) { @@ -207,7 +215,7 @@ public class EditShortcutsPreferenceFragmentTest { public void fragmentDestroyed_unregisterSettingsObserver() { ShadowContentResolver contentResolver = shadowOf(mContext.getContentResolver()); - mFragmentScenario = createFragScenario(/* isInSuw= */ false) + mFragmentScenario = createFragScenario(/* isInSuw= */ false, TARGET) .moveToState(Lifecycle.State.CREATED); mFragmentScenario.onFragment(EditShortcutsPreferenceFragment::onDestroy); @@ -218,7 +226,7 @@ public class EditShortcutsPreferenceFragmentTest { @Test public void onVolumeKeysShortcutSettingChanged_volumeKeyControllerUpdated() { - mFragmentScenario = createFragScenario(/* isInSuw= */ false); + mFragmentScenario = createFragScenario(/* isInSuw= */ false, TARGET); mFragmentScenario.moveToState(Lifecycle.State.CREATED); ShortcutUtils.optInValueToSettings( @@ -233,7 +241,7 @@ public class EditShortcutsPreferenceFragmentTest { @Test public void onSoftwareShortcutSettingChanged_softwareControllersUpdated() { - mFragmentScenario = createFragScenario(/* isInSuw= */ false); + mFragmentScenario = createFragScenario(/* isInSuw= */ false, TARGET); mFragmentScenario.moveToState(Lifecycle.State.CREATED); ShortcutUtils.optInValueToSettings( @@ -249,7 +257,7 @@ public class EditShortcutsPreferenceFragmentTest { @Test public void onSoftwareShortcutModeChanged_softwareControllersUpdated() { - mFragmentScenario = createFragScenario(/* isInSuw= */ false); + mFragmentScenario = createFragScenario(/* isInSuw= */ false, TARGET); mFragmentScenario.moveToState(Lifecycle.State.CREATED); ShortcutUtils.optInValueToSettings( @@ -265,7 +273,7 @@ public class EditShortcutsPreferenceFragmentTest { @Test public void onTripleTapShortcutSettingChanged_tripleTapShortcutControllerUpdated() { - mFragmentScenario = createFragScenario(/* isInSuw= */ false); + mFragmentScenario = createFragScenario(/* isInSuw= */ false, TARGET); mFragmentScenario.moveToState(Lifecycle.State.CREATED); Settings.Secure.putInt( @@ -283,7 +291,7 @@ public class EditShortcutsPreferenceFragmentTest { @Test public void onTwoFingersShortcutSettingChanged_twoFingersDoubleTapShortcutControllerUpdated() { - mFragmentScenario = createFragScenario(/* isInSuw= */ false); + mFragmentScenario = createFragScenario(/* isInSuw= */ false, TARGET); mFragmentScenario.moveToState(Lifecycle.State.CREATED); Settings.Secure.putInt( @@ -302,12 +310,12 @@ public class EditShortcutsPreferenceFragmentTest { @Test public void fragmentResumed_enableTouchExploration_gestureShortcutOptionSummaryUpdated() { - String expectedSummary = mContext.getString( - R.string.accessibility_shortcut_edit_dialog_summary_software_gesture_talkback) + String expectedSummary = StringUtil.getIcuPluralsString(mContext, 3, + R.string.accessibility_shortcut_edit_dialog_summary_gesture) + "\n\n" + mContext.getString( - R.string.accessibility_shortcut_edit_dialog_summary_software_floating); - mFragmentScenario = createFragScenario(/* isInSuw= */ false); + R.string.accessibility_shortcut_edit_dialog_summary_software_floating); + mFragmentScenario = createFragScenario(/* isInSuw= */ false, TARGET); mFragmentScenario.moveToState(Lifecycle.State.RESUMED); ShadowAccessibilityManager am = shadowOf( @@ -323,12 +331,12 @@ public class EditShortcutsPreferenceFragmentTest { @Test public void fragmentPaused_enableTouchExploration_gestureShortcutOptionSummaryNotUpdated() { - String expectedSummary = mContext.getString( - R.string.accessibility_shortcut_edit_dialog_summary_software_gesture) + String expectedSummary = StringUtil.getIcuPluralsString(mContext, 2, + R.string.accessibility_shortcut_edit_dialog_summary_gesture) + "\n\n" + mContext.getString( - R.string.accessibility_shortcut_edit_dialog_summary_software_floating); - mFragmentScenario = createFragScenario(/* isInSuw= */ false); + R.string.accessibility_shortcut_edit_dialog_summary_software_floating); + mFragmentScenario = createFragScenario(/* isInSuw= */ false, TARGET); mFragmentScenario.moveToState(Lifecycle.State.RESUMED).moveToState(Lifecycle.State.STARTED); ShadowAccessibilityManager am = shadowOf( @@ -342,9 +350,49 @@ public class EditShortcutsPreferenceFragmentTest { }); } + @Test + @EnableFlags(Flags.FLAG_A11Y_QS_SHORTCUT) + public void fragmentResumed_enableTouchExploration_qsShortcutOptionSummaryUpdated() { + String expectedSummary = StringUtil.getIcuPluralsString(mContext, 2, + R.string.accessibility_shortcut_edit_dialog_summary_quick_settings); + mFragmentScenario = createFragScenario( + /* isInSuw= */ false, TARGET_FAKE_COMPONENT.flattenToString()); + mFragmentScenario.moveToState(Lifecycle.State.RESUMED); + + ShadowAccessibilityManager am = shadowOf( + mContext.getSystemService(AccessibilityManager.class)); + am.setTouchExplorationEnabled(true); + + mFragmentScenario.onFragment(fragment -> { + Preference preference = fragment.findPreference( + mContext.getString(R.string.accessibility_shortcut_quick_settings_pref)); + assertThat(preference.getSummary().toString()).isEqualTo(expectedSummary); + }); + } + + @Test + @EnableFlags(Flags.FLAG_A11Y_QS_SHORTCUT) + public void fragmentPaused_enableTouchExploration_qsShortcutOptionSummaryNotUpdated() { + String expectedSummary = StringUtil.getIcuPluralsString(mContext, 1, + R.string.accessibility_shortcut_edit_dialog_summary_quick_settings); + mFragmentScenario = createFragScenario( + /* isInSuw= */ false, TARGET_FAKE_COMPONENT.flattenToString()); + mFragmentScenario.moveToState(Lifecycle.State.RESUMED).moveToState(Lifecycle.State.STARTED); + + ShadowAccessibilityManager am = shadowOf( + mContext.getSystemService(AccessibilityManager.class)); + am.setTouchExplorationEnabled(true); + + mFragmentScenario.onFragment(fragment -> { + Preference preference = fragment.findPreference( + mContext.getString(R.string.accessibility_shortcut_quick_settings_pref)); + assertThat(preference.getSummary().toString()).isEqualTo(expectedSummary); + }); + } + @Test public void onAdvancedPreferenceClicked_advancedShouldBecomeInvisible() { - mFragmentScenario = createFragScenario(/* isInSuw= */ false); + mFragmentScenario = createFragScenario(/* isInSuw= */ false, TARGET); mFragmentScenario.moveToState(Lifecycle.State.RESUMED); mFragmentScenario.onFragment(fragment -> { Preference advanced = fragment.findPreference( @@ -372,7 +420,7 @@ public class EditShortcutsPreferenceFragmentTest { @Test public void fragmentRecreated_collapsed_advancedRemainVisible() { - mFragmentScenario = createFragScenario(/* isInSuw= */ false); + mFragmentScenario = createFragScenario(/* isInSuw= */ false, TARGET); mFragmentScenario.moveToState(Lifecycle.State.RESUMED); mFragmentScenario.recreate(); @@ -386,7 +434,7 @@ public class EditShortcutsPreferenceFragmentTest { @Test public void fragmentResumed_preferredShortcutsUpdated() { - mFragmentScenario = createFragScenario(/* isInSuw= */ false); + mFragmentScenario = createFragScenario(/* isInSuw= */ false, TARGET); mFragmentScenario.moveToState(Lifecycle.State.RESUMED); // Move the fragment to the background mFragmentScenario.moveToState(Lifecycle.State.CREATED); @@ -408,7 +456,7 @@ public class EditShortcutsPreferenceFragmentTest { @Test public void onVolumeKeysShortcutSettingChanged_preferredShortcutsUpdated() { - mFragmentScenario = createFragScenario(/* isInSuw= */ false); + mFragmentScenario = createFragScenario(/* isInSuw= */ false, TARGET); mFragmentScenario.moveToState(Lifecycle.State.CREATED); assertThat( PreferredShortcuts.retrieveUserShortcutType( @@ -481,22 +529,25 @@ public class EditShortcutsPreferenceFragmentTest { } @Test + @EnableFlags(Flags.FLAG_A11Y_QS_SHORTCUT) public void onQuickSettingsShortcutSettingChanged_preferredShortcutsUpdated() { - mFragmentScenario = createFragScenario(/* isInSuw= */ false); + final String target = TARGET_FAKE_COMPONENT.flattenToString(); + mFragmentScenario = createFragScenario( + /* isInSuw= */ false, TARGET_FAKE_COMPONENT.flattenToString()); mFragmentScenario.moveToState(Lifecycle.State.CREATED); int currentPreferredShortcut = - PreferredShortcuts.retrieveUserShortcutType(mContext, TARGET); + PreferredShortcuts.retrieveUserShortcutType(mContext, target); assertThat(currentPreferredShortcut & ShortcutConstants.UserShortcutType.QUICK_SETTINGS).isEqualTo(0); ShortcutUtils.optInValueToSettings( - mContext, ShortcutConstants.UserShortcutType.QUICK_SETTINGS, TARGET); + mContext, ShortcutConstants.UserShortcutType.QUICK_SETTINGS, target); // Calls onFragment so that the change to Setting is notified to its observer mFragmentScenario.onFragment(fragment -> assertThat( PreferredShortcuts.retrieveUserShortcutType( - mContext, TARGET) + mContext, target) ).isEqualTo(ShortcutConstants.UserShortcutType.QUICK_SETTINGS) ); } @@ -537,10 +588,11 @@ public class EditShortcutsPreferenceFragmentTest { return retControllers; } - private FragmentScenario createFragScenario(boolean isInSuw) { + private FragmentScenario createFragScenario( + boolean isInSuw, String target) { Bundle args = new Bundle(); args.putStringArray( - EditShortcutsPreferenceFragment.ARG_KEY_SHORTCUT_TARGETS, new String[]{TARGET}); + EditShortcutsPreferenceFragment.ARG_KEY_SHORTCUT_TARGETS, new String[]{target}); FragmentScenario scenario = FragmentScenario.launch( EditShortcutsPreferenceFragment.class, args, diff --git a/tests/robotests/src/com/android/settings/accessibility/shortcuts/FloatingButtonShortcutOptionControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/shortcuts/FloatingButtonShortcutOptionControllerTest.java index b39aa226239..20f5d5da1fa 100644 --- a/tests/robotests/src/com/android/settings/accessibility/shortcuts/FloatingButtonShortcutOptionControllerTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/shortcuts/FloatingButtonShortcutOptionControllerTest.java @@ -24,7 +24,6 @@ import static com.google.common.truth.Truth.assertThat; import android.content.ComponentName; import android.content.Context; import android.provider.Settings; -import android.text.TextUtils; import androidx.preference.PreferenceManager; import androidx.preference.PreferenceScreen; @@ -74,19 +73,24 @@ public class FloatingButtonShortcutOptionControllerTest { } @Test - public void getSummary_inSuw_verifySummaryEmpty() { + public void getSummary_inSuw_verifySummary() { + String expectedSummary = mContext.getString( + R.string.accessibility_shortcut_edit_dialog_summary_floating_button); mController.setInSetupWizard(true); - assertThat(TextUtils.isEmpty(mController.getSummary())).isTrue(); + assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary); } @Test public void getSummary_notInSuw_verifySummary() { + String expectedSummary = mContext.getText( + R.string.accessibility_shortcut_edit_dialog_summary_floating_button) + + "\n\n" + + mContext.getString( + R.string.accessibility_shortcut_edit_dialog_summary_software_floating); mController.setInSetupWizard(false); - assertThat(mController.getSummary().toString()).isEqualTo( - mContext.getString( - R.string.accessibility_shortcut_edit_dialog_summary_software_floating)); + assertThat(mController.getSummary().toString()).isEqualTo(expectedSummary); } @Test diff --git a/tests/robotests/src/com/android/settings/accessibility/shortcuts/GestureShortcutOptionControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/shortcuts/GestureShortcutOptionControllerTest.java index 155cb2239b1..0149cc3520f 100644 --- a/tests/robotests/src/com/android/settings/accessibility/shortcuts/GestureShortcutOptionControllerTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/shortcuts/GestureShortcutOptionControllerTest.java @@ -34,6 +34,7 @@ import androidx.test.core.app.ApplicationProvider; import com.android.settings.R; import com.android.settings.testutils.AccessibilityTestUtils; import com.android.settings.testutils.shadow.SettingsShadowResources; +import com.android.settingslib.utils.StringUtil; import org.junit.Before; import org.junit.Test; @@ -82,10 +83,13 @@ public class GestureShortcutOptionControllerTest { } @Test - public void getSummary_touchExplorationDisabled_verifySummary() { + public void getSummary_touchExplorationDisabled_notInSuw_verifySummary() { enableTouchExploration(false); - String expected = mContext.getString( - R.string.accessibility_shortcut_edit_dialog_summary_software_gesture) + mController.setInSetupWizard(false); + String expected = StringUtil.getIcuPluralsString( + mContext, + /* count= */ 2, + R.string.accessibility_shortcut_edit_dialog_summary_gesture) + "\n\n" + mContext.getString( R.string.accessibility_shortcut_edit_dialog_summary_software_floating); @@ -94,10 +98,25 @@ public class GestureShortcutOptionControllerTest { } @Test - public void getSummary_touchExplorationEnabled_verifySummary() { + public void getSummary_touchExplorationDisabled_inSuw_verifySummary() { + enableTouchExploration(false); + mController.setInSetupWizard(true); + String expected = StringUtil.getIcuPluralsString( + mContext, + /* count= */ 2, + R.string.accessibility_shortcut_edit_dialog_summary_gesture); + + assertThat(mController.getSummary().toString()).isEqualTo(expected); + } + + @Test + public void getSummary_touchExplorationEnabled_notInSuw_verifySummary() { enableTouchExploration(true); - String expected = mContext.getString( - R.string.accessibility_shortcut_edit_dialog_summary_software_gesture_talkback) + mController.setInSetupWizard(false); + String expected = StringUtil.getIcuPluralsString( + mContext, + /* count= */ 3, + R.string.accessibility_shortcut_edit_dialog_summary_gesture) + "\n\n" + mContext.getString( R.string.accessibility_shortcut_edit_dialog_summary_software_floating); @@ -105,6 +124,18 @@ public class GestureShortcutOptionControllerTest { assertThat(mController.getSummary().toString()).isEqualTo(expected); } + @Test + public void getSummary_touchExplorationEnabled_inSuw_verifySummary() { + enableTouchExploration(true); + mController.setInSetupWizard(true); + String expected = StringUtil.getIcuPluralsString( + mContext, + /* count= */ 3, + R.string.accessibility_shortcut_edit_dialog_summary_gesture); + + assertThat(mController.getSummary().toString()).isEqualTo(expected); + } + @Test public void isShortcutAvailable_inSuw_returnFalse() { mController.setInSetupWizard(true); diff --git a/tests/robotests/src/com/android/settings/accessibility/shortcuts/QuickSettingsShortcutOptionControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/shortcuts/QuickSettingsShortcutOptionControllerTest.java index 6086b171d8c..55fbd8e3249 100644 --- a/tests/robotests/src/com/android/settings/accessibility/shortcuts/QuickSettingsShortcutOptionControllerTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/shortcuts/QuickSettingsShortcutOptionControllerTest.java @@ -16,6 +16,8 @@ package com.android.settings.accessibility.shortcuts; +import static com.android.settings.testutils.AccessibilityTestUtils.setupMockAccessibilityManager; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.spy; @@ -40,12 +42,14 @@ import com.android.internal.accessibility.util.ShortcutUtils; import com.android.settings.R; import com.android.settings.testutils.AccessibilityTestUtils; import com.android.settings.testutils.shadow.SettingsShadowResources; +import com.android.settingslib.utils.StringUtil; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; import java.util.Collections; import java.util.List; @@ -55,6 +59,7 @@ import java.util.Set; /** * Tests for {@link QuickSettingsShortcutOptionController} */ +@Config(shadows = SettingsShadowResources.class) @RunWith(RobolectricTestRunner.class) public class QuickSettingsShortcutOptionControllerTest { private static final String PREF_KEY = "prefKey"; @@ -87,15 +92,60 @@ public class QuickSettingsShortcutOptionControllerTest { } @Test - public void displayPreference_verifyScreenTextSet() { + public void displayPreference_verifyScreenTitleSet() { mController.displayPreference(mPreferenceScreen); assertThat(mShortcutOptionPreference.getTitle().toString()).isEqualTo( mContext.getString( R.string.accessibility_shortcut_edit_dialog_title_quick_settings)); - assertThat(mShortcutOptionPreference.getSummary().toString()).isEqualTo( - mContext.getString( - R.string.accessibility_shortcut_edit_dialog_summary_quick_settings)); + } + + @Test + public void getSummary_touchExplorationDisabled_inSuw_verifySummary() { + enableTouchExploration(false); + mController.setInSetupWizard(true); + String expected = StringUtil.getIcuPluralsString( + mContext, + /* count= */ 1, + R.string.accessibility_shortcut_edit_dialog_summary_quick_settings_suw); + + assertThat(mController.getSummary().toString()).isEqualTo(expected); + } + + @Test + public void getSummary_touchExplorationDisabled_notInSuw_verifySummary() { + enableTouchExploration(false); + mController.setInSetupWizard(false); + String expected = StringUtil.getIcuPluralsString( + mContext, + /* count= */ 1, + R.string.accessibility_shortcut_edit_dialog_summary_quick_settings); + + assertThat(mController.getSummary().toString()).isEqualTo(expected); + } + + @Test + public void getSummary_touchExplorationEnabled_inSuw_verifySummary() { + enableTouchExploration(true); + mController.setInSetupWizard(true); + String expected = StringUtil.getIcuPluralsString( + mContext, + /* count= */ 2, + R.string.accessibility_shortcut_edit_dialog_summary_quick_settings_suw); + + assertThat(mController.getSummary().toString()).isEqualTo(expected); + } + + @Test + public void getSummary_touchExplorationEnabled_notInSuw_verifySummary() { + enableTouchExploration(true); + mController.setInSetupWizard(false); + String expected = StringUtil.getIcuPluralsString( + mContext, + /* count= */ 2, + R.string.accessibility_shortcut_edit_dialog_summary_quick_settings); + + assertThat(mController.getSummary().toString()).isEqualTo(expected); } @Test @@ -177,4 +227,9 @@ public class QuickSettingsShortcutOptionControllerTest { assertThat(mController.isChecked()).isFalse(); } + + private void enableTouchExploration(boolean enable) { + AccessibilityManager am = setupMockAccessibilityManager(mContext); + when(am.isTouchExplorationEnabled()).thenReturn(enable); + } } diff --git a/tests/robotests/src/com/android/settings/accessibility/shortcuts/TripleTapShortcutOptionControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/shortcuts/TripleTapShortcutOptionControllerTest.java index b5daac5f5fb..1ffd042b172 100644 --- a/tests/robotests/src/com/android/settings/accessibility/shortcuts/TripleTapShortcutOptionControllerTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/shortcuts/TripleTapShortcutOptionControllerTest.java @@ -27,7 +27,6 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import android.content.ComponentName; import android.content.Context; -import android.icu.text.MessageFormat; import android.os.UserHandle; import android.platform.test.annotations.DisableFlags; import android.platform.test.annotations.EnableFlags; @@ -83,16 +82,16 @@ public class TripleTapShortcutOptionControllerTest { } @Test - public void displayPreference_verifyScreenTestSet() { + public void displayPreference_verifyTitleSummaryText() { + String expectedTitle = mContext.getString( + R.string.accessibility_shortcut_edit_screen_title_triple_tap); + String expectedSummary = mContext.getString( + R.string.accessibility_shortcut_edit_screen_summary_triple_tap, 3); + mController.displayPreference(mPreferenceScreen); - assertThat(mShortcutOptionPreference.getTitle().toString()).isEqualTo( - mContext.getString(R.string.accessibility_shortcut_edit_dialog_title_triple_tap)); - assertThat(mShortcutOptionPreference.getSummary().toString()).isEqualTo( - MessageFormat.format( - mContext.getString( - R.string.accessibility_shortcut_edit_dialog_summary_triple_tap), - 3)); + assertThat(mShortcutOptionPreference.getTitle().toString()).isEqualTo(expectedTitle); + assertThat(mShortcutOptionPreference.getSummary().toString()).isEqualTo(expectedSummary); } @Test diff --git a/tests/robotests/src/com/android/settings/accessibility/shortcuts/TwoFingerDoubleTapShortcutOptionControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/shortcuts/TwoFingerDoubleTapShortcutOptionControllerTest.java index 716dcdbf274..dde60e902fa 100644 --- a/tests/robotests/src/com/android/settings/accessibility/shortcuts/TwoFingerDoubleTapShortcutOptionControllerTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/shortcuts/TwoFingerDoubleTapShortcutOptionControllerTest.java @@ -24,7 +24,6 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import android.content.ComponentName; import android.content.Context; -import android.icu.text.MessageFormat; import android.os.UserHandle; import android.platform.test.annotations.DisableFlags; import android.platform.test.annotations.EnableFlags; @@ -82,15 +81,15 @@ public class TwoFingerDoubleTapShortcutOptionControllerTest { @Test public void displayPreference_verifyScreenTextSet() { + String expectedTitle = mContext.getString( + R.string.accessibility_shortcut_edit_screen_title_two_finger_double_tap, 2); + String expectedSummary = mContext.getString( + R.string.accessibility_shortcut_edit_screen_summary_two_finger_double_tap, 2); + mController.displayPreference(mPreferenceScreen); - assertThat(mShortcutOptionPreference.getTitle().toString()).isEqualTo( - mContext.getString( - R.string.accessibility_shortcut_edit_dialog_title_two_finger_double_tap)); - assertThat(mShortcutOptionPreference.getSummary().toString()).isEqualTo( - MessageFormat.format(mContext.getString( - R.string.accessibility_shortcut_edit_dialog_summary_two_finger_double_tap), - 2)); + assertThat(mShortcutOptionPreference.getTitle().toString()).isEqualTo(expectedTitle); + assertThat(mShortcutOptionPreference.getSummary().toString()).isEqualTo(expectedSummary); } @Test diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowAccessibilityManager.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowAccessibilityManager.java index d6e17d46d40..de7792c2ec0 100644 --- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowAccessibilityManager.java +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowAccessibilityManager.java @@ -16,14 +16,15 @@ package com.android.settings.testutils.shadow; +import android.annotation.NonNull; import android.annotation.UserIdInt; import android.content.ComponentName; +import android.util.ArrayMap; import android.view.accessibility.AccessibilityManager; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; -import java.util.Collections; import java.util.Map; /** @@ -31,12 +32,21 @@ import java.util.Map; */ @Implements(AccessibilityManager.class) public class ShadowAccessibilityManager extends org.robolectric.shadows.ShadowAccessibilityManager { + private Map mA11yFeatureToTileMap = new ArrayMap<>(); + /** - * Implements a hidden method {@link AccessibilityManager.getA11yFeatureToTileMap} and returns - * an empty map. + * Implements a hidden method {@link AccessibilityManager.getA11yFeatureToTileMap} */ @Implementation public Map getA11yFeatureToTileMap(@UserIdInt int userId) { - return Collections.emptyMap(); + return mA11yFeatureToTileMap; + } + + /** + * Set fake a11y feature to tile mapping + */ + public void setA11yFeatureToTileMap( + @NonNull Map a11yFeatureToTileMap) { + mA11yFeatureToTileMap = a11yFeatureToTileMap; } }