Merge "Save the user preferred shortcut on Edit A11yShortcut screen" into main
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);
+ }
}