From 1e80db4ee376a075a8841b3564d2c7e9034f5145 Mon Sep 17 00:00:00 2001 From: Riley Jones Date: Tue, 2 Jul 2024 03:22:41 +0000 Subject: [PATCH] Adjust edit shortcuts page to display button & gesture Page is altered to display the FAB shortcut and gesture shortcut simultaneously when the user is in gesture navigation mode. The gesture option does not display the "more options" link. Additionally, the gesture option controller uses the GESTURE type, which means it will read from & write to the gesture setting. All this behavior is flag protected. Bug: 300318311 Test: atest FloatingButtonShortcutOptionControllerTest GestureShortcutOptionControllerTest Flag: android.provider.a11y_standalone_gesture_enabled Change-Id: I915f05b2102ce499bb906df2c13e0870ae0a36d5 --- .../EditShortcutsPreferenceFragment.java | 7 ++- ...loatingButtonShortcutOptionController.java | 9 +++- .../GestureShortcutOptionController.java | 24 +++++++--- ...ingButtonShortcutOptionControllerTest.java | 37 ++++++++++------ .../GestureShortcutOptionControllerTest.java | 44 +++++++++++++++++++ .../testutils/AccessibilityTestUtils.java | 21 ++++----- 6 files changed, 109 insertions(+), 33 deletions(-) diff --git a/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragment.java b/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragment.java index bdf785766c2..d04b34a4c3f 100644 --- a/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragment.java +++ b/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragment.java @@ -20,6 +20,7 @@ import static android.app.Activity.RESULT_CANCELED; import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE; import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS; import static android.provider.Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED; +import static android.provider.Settings.Secure.ACCESSIBILITY_GESTURE_TARGETS; import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_TWO_FINGER_TRIPLE_TAP_ENABLED; import static android.provider.Settings.Secure.ACCESSIBILITY_QS_TARGETS; import static android.provider.Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE; @@ -93,7 +94,8 @@ public class EditShortcutsPreferenceFragment extends DashboardFragment { Settings.Secure.getUriFor(ACCESSIBILITY_BUTTON_MODE); private static final Uri BUTTON_SHORTCUT_SETTING = Settings.Secure.getUriFor(ACCESSIBILITY_BUTTON_TARGETS); - + private static final Uri GESTURE_SHORTCUT_SETTING = + Settings.Secure.getUriFor(ACCESSIBILITY_GESTURE_TARGETS); private static final Uri TRIPLE_TAP_SHORTCUT_SETTING = Settings.Secure.getUriFor(ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED); private static final Uri TWO_FINGERS_DOUBLE_TAP_SHORTCUT_SETTING = @@ -107,6 +109,7 @@ public class EditShortcutsPreferenceFragment extends DashboardFragment { VOLUME_KEYS_SHORTCUT_SETTING, BUTTON_SHORTCUT_MODE_SETTING, BUTTON_SHORTCUT_SETTING, + GESTURE_SHORTCUT_SETTING, TRIPLE_TAP_SHORTCUT_SETTING, TWO_FINGERS_DOUBLE_TAP_SHORTCUT_SETTING, QUICK_SETTINGS_SHORTCUT_SETTING, @@ -173,6 +176,8 @@ public class EditShortcutsPreferenceFragment extends DashboardFragment { } else if (BUTTON_SHORTCUT_MODE_SETTING.equals(uri) || BUTTON_SHORTCUT_SETTING.equals(uri)) { refreshSoftwareShortcutControllers(); + } else if (GESTURE_SHORTCUT_SETTING.equals(uri)) { + refreshPreferenceController(GestureShortcutOptionController.class); } else if (TRIPLE_TAP_SHORTCUT_SETTING.equals(uri)) { refreshPreferenceController(TripleTapShortcutOptionController.class); } else if (TWO_FINGERS_DOUBLE_TAP_SHORTCUT_SETTING.equals(uri)) { diff --git a/src/com/android/settings/accessibility/shortcuts/FloatingButtonShortcutOptionController.java b/src/com/android/settings/accessibility/shortcuts/FloatingButtonShortcutOptionController.java index 2242cabba8a..20ff12d46fb 100644 --- a/src/com/android/settings/accessibility/shortcuts/FloatingButtonShortcutOptionController.java +++ b/src/com/android/settings/accessibility/shortcuts/FloatingButtonShortcutOptionController.java @@ -50,7 +50,14 @@ public class FloatingButtonShortcutOptionController @Override protected boolean isShortcutAvailable() { - return AccessibilityUtil.isFloatingMenuEnabled(mContext); + if (android.provider.Flags.a11yStandaloneGestureEnabled()) { + // FAB should be available when in gesture navigation mode, + // or if we're in the FAB button mode while in navbar navigation mode. + return AccessibilityUtil.isGestureNavigateEnabled(mContext) + || AccessibilityUtil.isFloatingMenuEnabled(mContext); + } else { + return AccessibilityUtil.isFloatingMenuEnabled(mContext); + } } @Nullable diff --git a/src/com/android/settings/accessibility/shortcuts/GestureShortcutOptionController.java b/src/com/android/settings/accessibility/shortcuts/GestureShortcutOptionController.java index e65aab9a14a..3c19b5dd10e 100644 --- a/src/com/android/settings/accessibility/shortcuts/GestureShortcutOptionController.java +++ b/src/com/android/settings/accessibility/shortcuts/GestureShortcutOptionController.java @@ -16,6 +16,8 @@ package com.android.settings.accessibility.shortcuts; +import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.GESTURE; + import android.content.Context; import android.text.SpannableStringBuilder; @@ -51,11 +53,22 @@ public class GestureShortcutOptionController extends SoftwareShortcutOptionPrefe } } + @Override + protected int getShortcutType() { + return android.provider.Flags.a11yStandaloneGestureEnabled() + ? GESTURE : super.getShortcutType(); + } + @Override protected boolean isShortcutAvailable() { - return !isInSetupWizard() - && !AccessibilityUtil.isFloatingMenuEnabled(mContext) - && AccessibilityUtil.isGestureNavigateEnabled(mContext); + if (android.provider.Flags.a11yStandaloneGestureEnabled()) { + return !isInSetupWizard() + && AccessibilityUtil.isGestureNavigateEnabled(mContext); + } else { + return !isInSetupWizard() + && AccessibilityUtil.isGestureNavigateEnabled(mContext) + && !AccessibilityUtil.isFloatingMenuEnabled(mContext); + } } @Override @@ -68,9 +81,8 @@ public class GestureShortcutOptionController extends SoftwareShortcutOptionPrefe final SpannableStringBuilder sb = new SpannableStringBuilder(); sb.append(instruction); - if (!isInSetupWizard()) { - sb.append("\n\n"); - sb.append(getCustomizeAccessibilityButtonLink()); + if (!isInSetupWizard() && !android.provider.Flags.a11yStandaloneGestureEnabled()) { + sb.append("\n\n").append(getCustomizeAccessibilityButtonLink()); } return sb; 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 20f5d5da1fa..0952b099f38 100644 --- a/tests/robotests/src/com/android/settings/accessibility/shortcuts/FloatingButtonShortcutOptionControllerTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/shortcuts/FloatingButtonShortcutOptionControllerTest.java @@ -16,37 +16,46 @@ package com.android.settings.accessibility.shortcuts; -import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU; -import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_GESTURE; - import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.spy; + import android.content.ComponentName; import android.content.Context; -import android.provider.Settings; +import android.platform.test.annotations.EnableFlags; +import android.platform.test.flag.junit.SetFlagsRule; +import android.provider.Flags; import androidx.preference.PreferenceManager; import androidx.preference.PreferenceScreen; 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 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.Set; /** * Tests for {@link FloatingButtonShortcutOptionController} */ +@Config(shadows = SettingsShadowResources.class) @RunWith(RobolectricTestRunner.class) public class FloatingButtonShortcutOptionControllerTest { + @Rule + public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + private static final String PREF_KEY = "prefKey"; private static final String TARGET = new ComponentName("FakePackage", "FakeClass").flattenToString(); - private final Context mContext = ApplicationProvider.getApplicationContext(); + private final Context mContext = spy(ApplicationProvider.getApplicationContext()); private FloatingButtonShortcutOptionController mController; private ShortcutOptionPreference mShortcutOptionPreference; @@ -61,7 +70,6 @@ public class FloatingButtonShortcutOptionControllerTest { mShortcutOptionPreference.setKey(PREF_KEY); mPreferenceScreen = new PreferenceManager(mContext).createPreferenceScreen(mContext); mPreferenceScreen.addPreference(mShortcutOptionPreference); - setFloatingButtonEnabled(true); } @Test @@ -95,23 +103,26 @@ public class FloatingButtonShortcutOptionControllerTest { @Test public void isShortcutAvailable_floatingMenuEnabled_returnTrue() { - setFloatingButtonEnabled(true); + AccessibilityTestUtils.setSoftwareShortcutMode( + mContext, /* gestureNavEnabled= */ false, /* floatingButtonEnabled= */ true); assertThat(mController.isShortcutAvailable()).isTrue(); } @Test public void isShortcutAvailable_floatingMenuDisabled_returnFalse() { - setFloatingButtonEnabled(false); + AccessibilityTestUtils.setSoftwareShortcutMode( + mContext, /* gestureNavEnabled= */ false, /* floatingButtonEnabled= */ false); assertThat(mController.isShortcutAvailable()).isFalse(); } - private void setFloatingButtonEnabled(boolean enable) { - int mode = enable - ? ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU : ACCESSIBILITY_BUTTON_MODE_GESTURE; + @Test + @EnableFlags(Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED) + public void isShortcutAvailable_gestureNavigationMode_returnsTrue() { + AccessibilityTestUtils.setSoftwareShortcutMode( + mContext, /* gestureNavEnabled= */ true, /* floatingButtonEnabled= */ false); - Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.ACCESSIBILITY_BUTTON_MODE, mode); + assertThat(mController.isShortcutAvailable()).isTrue(); } } 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 0149cc3520f..1d46caef087 100644 --- a/tests/robotests/src/com/android/settings/accessibility/shortcuts/GestureShortcutOptionControllerTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/shortcuts/GestureShortcutOptionControllerTest.java @@ -16,6 +16,8 @@ package com.android.settings.accessibility.shortcuts; +import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.GESTURE; +import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE; import static com.android.settings.testutils.AccessibilityTestUtils.setupMockAccessibilityManager; import static com.google.common.truth.Truth.assertThat; @@ -25,6 +27,10 @@ import static org.mockito.Mockito.when; import android.content.ComponentName; import android.content.Context; +import android.platform.test.annotations.DisableFlags; +import android.platform.test.annotations.EnableFlags; +import android.platform.test.flag.junit.SetFlagsRule; +import android.provider.Flags; import android.view.accessibility.AccessibilityManager; import androidx.preference.PreferenceManager; @@ -37,6 +43,7 @@ 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; @@ -50,6 +57,8 @@ import java.util.Set; @Config(shadows = SettingsShadowResources.class) @RunWith(RobolectricTestRunner.class) public class GestureShortcutOptionControllerTest { + @Rule + public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); private static final String PREF_KEY = "prefKey"; private static final String TARGET = new ComponentName("FakePackage", "FakeClass").flattenToString(); @@ -136,6 +145,18 @@ public class GestureShortcutOptionControllerTest { assertThat(mController.getSummary().toString()).isEqualTo(expected); } + @Test + @EnableFlags(Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED) + public void getSummary_standaloneGestureFlagOn_verifyNoCustomizeA11yButtonTest() { + enableTouchExploration(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); @@ -144,6 +165,7 @@ public class GestureShortcutOptionControllerTest { } @Test + @DisableFlags(Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED) public void isShortcutAvailable_notInSuwUseGestureNavSystemUseFab_returnFalse() { mController.setInSetupWizard(false); AccessibilityTestUtils.setSoftwareShortcutMode( @@ -179,6 +201,28 @@ public class GestureShortcutOptionControllerTest { assertThat(mController.isShortcutAvailable()).isFalse(); } + @EnableFlags(Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED) + @Test + public void isShortcutAvailable_floatingMenuEnabled_gestureNavEnabled_returnsTrue() { + mController.setInSetupWizard(false); + AccessibilityTestUtils.setSoftwareShortcutMode( + mContext, /* gestureNavEnabled= */ true, /* floatingButtonEnabled= */ true); + + assertThat(mController.isShortcutAvailable()).isTrue(); + } + + @EnableFlags(Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED) + @Test + public void getShortcutType_gesture() { + assertThat(mController.getShortcutType()).isEqualTo(GESTURE); + } + + @DisableFlags(Flags.FLAG_A11Y_STANDALONE_GESTURE_ENABLED) + @Test + public void getShortcutType_software() { + assertThat(mController.getShortcutType()).isEqualTo(SOFTWARE); + } + private void enableTouchExploration(boolean enable) { AccessibilityManager am = setupMockAccessibilityManager(mContext); when(am.isTouchExplorationEnabled()).thenReturn(enable); diff --git a/tests/robotests/src/com/android/settings/testutils/AccessibilityTestUtils.java b/tests/robotests/src/com/android/settings/testutils/AccessibilityTestUtils.java index 5d895d908d6..4d698215c43 100644 --- a/tests/robotests/src/com/android/settings/testutils/AccessibilityTestUtils.java +++ b/tests/robotests/src/com/android/settings/testutils/AccessibilityTestUtils.java @@ -20,6 +20,8 @@ import static android.provider.Settings.Secure.ACCESSIBILITY_BUTTON_MODE_FLOATIN import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON; import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL; +import static com.google.common.truth.Truth.assertThat; + import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -46,20 +48,15 @@ public class AccessibilityTestUtils { public static void setSoftwareShortcutMode( Context context, boolean gestureNavEnabled, boolean floatingButtonEnabled) { - int mode = floatingButtonEnabled ? ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU : -1; + int buttonMode = floatingButtonEnabled ? ACCESSIBILITY_BUTTON_MODE_FLOATING_MENU : -1; + int navMode = gestureNavEnabled ? NAV_BAR_MODE_GESTURAL : NAV_BAR_MODE_3BUTTON; Settings.Secure.putInt(context.getContentResolver(), - Settings.Secure.ACCESSIBILITY_BUTTON_MODE, mode); - - if (gestureNavEnabled) { - SettingsShadowResources.overrideResource( - com.android.internal.R.integer.config_navBarInteractionMode, - NAV_BAR_MODE_GESTURAL); - } else { - SettingsShadowResources.overrideResource( - com.android.internal.R.integer.config_navBarInteractionMode, - NAV_BAR_MODE_3BUTTON); - } + Settings.Secure.ACCESSIBILITY_BUTTON_MODE, buttonMode); + SettingsShadowResources.overrideResource( + com.android.internal.R.integer.config_navBarInteractionMode, navMode); + assertThat(context.getResources().getInteger( + com.android.internal.R.integer.config_navBarInteractionMode)).isEqualTo(navMode); } /**