Save the user preferred shortcut on Edit A11yShortcut screen
We saved the user preferred shortcut in the a11y feature's detail page.
Since now the Edit A11yShortcut screen is a standalone screen, we might
want to keep the existing behavior to update the user preferred shortcut
types when the edit screen is shown or when the shortcut settings are
updated.
Bug: 300302098
Test: atest
Test: manual
- Go to an a11y feature page and open the Edit shortcut screen
- Remove all selected shortcut option
- Select volume key shortcut option, and deselect volume key
shortcut option
- Go to home page and close the Settings app
- Go to the same a11y feature page and click on the shortcut toggle
- Expect the volume key shortcut is turned on
Flag: ACONFIG
com.android.settings.accessibility.edit_shortcuts_in_full_screen
TRUNKFOOD
Change-Id: I2c92ec56d6e45317406f3a4b8ef8f076c398df7f
diff --git a/src/com/android/settings/accessibility/PreferredShortcuts.java b/src/com/android/settings/accessibility/PreferredShortcuts.java
index 2c9840d..d4e8e0c 100644
--- a/src/com/android/settings/accessibility/PreferredShortcuts.java
+++ b/src/com/android/settings/accessibility/PreferredShortcuts.java
@@ -19,10 +19,17 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.SharedPreferences;
+import android.os.UserHandle;
+import android.util.ArrayMap;
+import androidx.annotation.NonNull;
+
+import com.android.internal.accessibility.common.ShortcutConstants;
+import com.android.internal.accessibility.util.ShortcutUtils;
import com.android.settings.accessibility.AccessibilityUtil.UserShortcutType;
import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
/** Static utility methods relating to {@link PreferredShortcut} */
@@ -81,6 +88,41 @@
}
/**
+ * Update the user preferred shortcut from Settings data
+ *
+ * @param context {@link Context} to access the {@link SharedPreferences}
+ * @param components contains a set of {@link ComponentName} the service or activity. The
+ * string
+ * representation of the ComponentName should be in the format of
+ * {@link ComponentName#flattenToString()}.
+ */
+ public static void updatePreferredShortcutsFromSettings(
+ @NonNull Context context, @NonNull Set<String> components) {
+ final Map<Integer, Set<String>> shortcutTypeToTargets = new ArrayMap<>();
+ for (int shortcutType : ShortcutConstants.USER_SHORTCUT_TYPES) {
+ shortcutTypeToTargets.put(
+ shortcutType,
+ ShortcutUtils.getShortcutTargetsFromSettings(
+ context, shortcutType, UserHandle.myUserId()));
+ }
+
+ for (String target : components) {
+ int shortcutTypes = ShortcutConstants.UserShortcutType.DEFAULT;
+ for (Map.Entry<Integer, Set<String>> entry : shortcutTypeToTargets.entrySet()) {
+ if (entry.getValue().contains(target)) {
+ shortcutTypes |= entry.getKey();
+ }
+ }
+
+ if (shortcutTypes != ShortcutConstants.UserShortcutType.DEFAULT) {
+ final PreferredShortcut shortcut = new PreferredShortcut(
+ target, shortcutTypes);
+ PreferredShortcuts.saveUserShortcutType(context, shortcut);
+ }
+ }
+ }
+
+ /**
* Returns a immutable set of {@link PreferredShortcut#toString()} list from
* SharedPreferences.
*/
diff --git a/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragment.java b/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragment.java
index 7a1dd4b..a3cbb57 100644
--- a/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragment.java
@@ -51,6 +51,7 @@
import com.android.settings.R;
import com.android.settings.SetupWizardUtils;
import com.android.settings.accessibility.AccessibilitySetupWizardUtils;
+import com.android.settings.accessibility.PreferredShortcuts;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settingslib.core.AbstractPreferenceController;
@@ -161,6 +162,9 @@
} else if (TWO_FINGERS_DOUBLE_TAP_SHORTCUT_SETTING.equals(uri)) {
refreshPreferenceController(TwoFingersDoubleTapShortcutOptionController.class);
}
+
+ PreferredShortcuts.updatePreferredShortcutsFromSettings(
+ getContext(), mShortcutTargets);
}
};
@@ -212,6 +216,7 @@
final AccessibilityManager am = getSystemService(
AccessibilityManager.class);
am.addTouchExplorationStateChangeListener(mTouchExplorationStateChangeListener);
+ PreferredShortcuts.updatePreferredShortcutsFromSettings(getContext(), mShortcutTargets);
}
@Override
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 53a87ba..7586954 100644
--- a/tests/robotests/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/shortcuts/EditShortcutsPreferenceFragmentTest.java
@@ -51,6 +51,7 @@
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.shadow.SettingsShadowResources;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
@@ -369,6 +370,50 @@
});
}
+ @Test
+ public void fragmentResumed_preferredShortcutsUpdated() {
+ mFragmentScenario = createFragScenario(/* isInSuw= */ false);
+ mFragmentScenario.moveToState(Lifecycle.State.RESUMED);
+ // Move the fragment to the background
+ mFragmentScenario.moveToState(Lifecycle.State.CREATED);
+ assertThat(
+ PreferredShortcuts.retrieveUserShortcutType(
+ mContext, TARGET, ShortcutConstants.UserShortcutType.SOFTWARE)
+ ).isEqualTo(ShortcutConstants.UserShortcutType.SOFTWARE);
+ // Update the chosen shortcut type to Volume keys while the fragment is in the background
+ ShortcutUtils.optInValueToSettings(
+ mContext, ShortcutConstants.UserShortcutType.HARDWARE, TARGET);
+
+ mFragmentScenario.moveToState(Lifecycle.State.RESUMED);
+
+ assertThat(
+ PreferredShortcuts.retrieveUserShortcutType(
+ mContext, TARGET, ShortcutConstants.UserShortcutType.SOFTWARE)
+ ).isEqualTo(ShortcutConstants.UserShortcutType.HARDWARE);
+ }
+
+ @Test
+ public void onVolumeKeysShortcutSettingChanged_preferredShortcutsUpdated() {
+ mFragmentScenario = createFragScenario(/* isInSuw= */ false);
+ mFragmentScenario.moveToState(Lifecycle.State.CREATED);
+ assertThat(
+ PreferredShortcuts.retrieveUserShortcutType(
+ mContext, TARGET, ShortcutConstants.UserShortcutType.SOFTWARE)
+ ).isEqualTo(ShortcutConstants.UserShortcutType.SOFTWARE);
+
+ ShortcutUtils.optInValueToSettings(
+ mContext, ShortcutConstants.UserShortcutType.HARDWARE, TARGET);
+
+ // Calls onFragment so that the change to Setting is notified to its observer
+ mFragmentScenario.onFragment(fragment ->
+ assertThat(
+ PreferredShortcuts.retrieveUserShortcutType(
+ mContext, TARGET, ShortcutConstants.UserShortcutType.SOFTWARE)
+ ).isEqualTo(ShortcutConstants.UserShortcutType.HARDWARE)
+ );
+
+ }
+
private void assertLaunchSubSettingWithCurrentTargetComponents(
String componentName, boolean isInSuw) {
Intent intent = shadowOf(mActivity.getApplication()).getNextStartedActivity();
diff --git a/tests/unit/src/com/android/settings/accessibility/PreferredShortcutsTest.java b/tests/unit/src/com/android/settings/accessibility/PreferredShortcutsTest.java
index 95a0b83..e7dfb5b 100644
--- a/tests/unit/src/com/android/settings/accessibility/PreferredShortcutsTest.java
+++ b/tests/unit/src/com/android/settings/accessibility/PreferredShortcutsTest.java
@@ -16,17 +16,30 @@
package com.android.settings.accessibility;
+import static com.android.internal.accessibility.AccessibilityShortcutController.COLOR_INVERSION_COMPONENT_NAME;
+import static com.android.internal.accessibility.AccessibilityShortcutController.DALTONIZER_COMPONENT_NAME;
+import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
+
import static com.google.common.truth.Truth.assertThat;
import android.content.ComponentName;
+import android.content.ContentResolver;
import android.content.Context;
+import android.provider.Settings;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
+import com.android.internal.accessibility.common.ShortcutConstants;
+import com.android.internal.accessibility.util.ShortcutUtils;
+
+import org.junit.AfterClass;
+import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.Set;
+
/** Tests for {@link PreferredShortcuts} */
@RunWith(AndroidJUnit4.class)
public class PreferredShortcutsTest {
@@ -39,8 +52,20 @@
private static final String CLASS_NAME_2 = PACKAGE_NAME_2 + ".test2";
private static final ComponentName COMPONENT_NAME_2 = new ComponentName(PACKAGE_NAME_2,
CLASS_NAME_2);
+ private static final ContentResolver sContentResolver =
+ ApplicationProvider.getApplicationContext().getContentResolver();
- private Context mContext = ApplicationProvider.getApplicationContext();
+ private final Context mContext = ApplicationProvider.getApplicationContext();
+
+ @Before
+ public void setUp() {
+ clearShortcuts();
+ }
+
+ @AfterClass
+ public static void cleanUp() {
+ clearShortcuts();
+ }
@Test
public void retrieveUserShortcutType_fromSingleData_matchSavedType() {
@@ -71,4 +96,88 @@
assertThat(retrieveType).isEqualTo(type1);
}
+
+ @Test
+ public void updatePreferredShortcutsFromSetting_magnificationWithTripleTapAndVolumeKeyShortcuts_preferredShortcutsMatches() {
+ ShortcutUtils.optInValueToSettings(mContext, ShortcutConstants.UserShortcutType.HARDWARE,
+ MAGNIFICATION_CONTROLLER_NAME);
+ Settings.Secure.putInt(
+ sContentResolver,
+ Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
+ AccessibilityUtil.State.ON);
+
+ PreferredShortcuts.updatePreferredShortcutsFromSettings(mContext,
+ Set.of(MAGNIFICATION_CONTROLLER_NAME));
+ int expectedShortcutTypes = ShortcutConstants.UserShortcutType.HARDWARE
+ | ShortcutConstants.UserShortcutType.TRIPLETAP;
+
+ assertThat(
+ PreferredShortcuts.retrieveUserShortcutType(
+ mContext, MAGNIFICATION_CONTROLLER_NAME,
+ ShortcutConstants.UserShortcutType.SOFTWARE))
+ .isEqualTo(expectedShortcutTypes);
+ }
+
+ @Test
+ public void updatePreferredShortcutsFromSetting_magnificationWithNoActiveShortcuts_noChangesOnPreferredShortcutTypes() {
+ int expectedShortcutTypes = ShortcutConstants.UserShortcutType.HARDWARE
+ | ShortcutConstants.UserShortcutType.SOFTWARE;
+ PreferredShortcuts.saveUserShortcutType(mContext,
+ new PreferredShortcut(MAGNIFICATION_CONTROLLER_NAME, expectedShortcutTypes));
+
+
+ PreferredShortcuts.updatePreferredShortcutsFromSettings(mContext,
+ Set.of(MAGNIFICATION_CONTROLLER_NAME));
+
+
+ assertThat(
+ PreferredShortcuts.retrieveUserShortcutType(
+ mContext, MAGNIFICATION_CONTROLLER_NAME,
+ ShortcutConstants.UserShortcutType.SOFTWARE))
+ .isEqualTo(expectedShortcutTypes);
+ }
+
+ @Test
+ public void updatePreferredShortcutsFromSetting_multipleComponents_preferredShortcutsMatches() {
+ String target1 = COLOR_INVERSION_COMPONENT_NAME.flattenToString();
+ String target2 = DALTONIZER_COMPONENT_NAME.flattenToString();
+
+ Settings.Secure.putString(sContentResolver,
+ Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, target1);
+ Settings.Secure.putString(sContentResolver,
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE,
+ target1 + ShortcutConstants.SERVICES_SEPARATOR + target2);
+
+ int target1ShortcutTypes = ShortcutConstants.UserShortcutType.HARDWARE
+ | ShortcutConstants.UserShortcutType.SOFTWARE;
+ int target2ShortcutTypes = ShortcutConstants.UserShortcutType.HARDWARE;
+
+ PreferredShortcuts.updatePreferredShortcutsFromSettings(mContext, Set.of(target1, target2));
+
+ assertThat(
+ PreferredShortcuts.retrieveUserShortcutType(
+ mContext, target1,
+ ShortcutConstants.UserShortcutType.SOFTWARE))
+ .isEqualTo(target1ShortcutTypes);
+ assertThat(
+ PreferredShortcuts.retrieveUserShortcutType(
+ mContext, target2,
+ ShortcutConstants.UserShortcutType.SOFTWARE))
+ .isEqualTo(target2ShortcutTypes);
+ }
+
+ private static void clearShortcuts() {
+ Settings.Secure.putString(sContentResolver,
+ Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, "");
+ Settings.Secure.putString(sContentResolver,
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, "");
+ Settings.Secure.putInt(
+ sContentResolver,
+ Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
+ AccessibilityUtil.State.OFF);
+ Settings.Secure.putInt(
+ sContentResolver,
+ Settings.Secure.ACCESSIBILITY_MAGNIFICATION_TWO_FINGER_TRIPLE_TAP_ENABLED,
+ AccessibilityUtil.State.OFF);
+ }
}