diff --git a/src/com/android/settings/accessibility/AccessibilityUtil.java b/src/com/android/settings/accessibility/AccessibilityUtil.java index 371afa1917c..06c114b5578 100644 --- a/src/com/android/settings/accessibility/AccessibilityUtil.java +++ b/src/com/android/settings/accessibility/AccessibilityUtil.java @@ -67,7 +67,7 @@ final class AccessibilityUtil { new TextUtils.SimpleStringSplitter(COMPONENT_NAME_SEPARATOR); /** - * Annotation for different shortcut type UI type. + * Annotation for different user shortcut type UI type. * * {@code DEFAULT} for displaying default value. * {@code SOFTWARE} for displaying specifying the accessibility services or features which @@ -79,14 +79,14 @@ final class AccessibilityUtil { */ @Retention(RetentionPolicy.SOURCE) @IntDef({ - PreferredShortcutType.DEFAULT, - PreferredShortcutType.SOFTWARE, - PreferredShortcutType.HARDWARE, - PreferredShortcutType.TRIPLETAP, + UserShortcutType.DEFAULT, + UserShortcutType.SOFTWARE, + UserShortcutType.HARDWARE, + UserShortcutType.TRIPLETAP, }) - /** Denotes the shortcut type. */ - public @interface PreferredShortcutType { + /** Denotes the user shortcut type. */ + public @interface UserShortcutType { int DEFAULT = 0; int SOFTWARE = 1; // 1 << 0 int HARDWARE = 2; // 1 << 1 @@ -166,7 +166,7 @@ final class AccessibilityUtil { * @param shortcutType The preferred shortcut type user selected. * @param componentName The component name that need to be opted in Settings. */ - static void optInValueToSettings(Context context, @PreferredShortcutType int shortcutType, + static void optInValueToSettings(Context context, @UserShortcutType int shortcutType, @NonNull ComponentName componentName) { final String targetKey = convertKeyFromSettings(shortcutType); final String targetString = Settings.Secure.getString(context.getContentResolver(), @@ -195,7 +195,7 @@ final class AccessibilityUtil { * @param shortcutType The preferred shortcut type user selected. * @param componentName The component name that need to be opted out from Settings. */ - static void optOutValueFromSettings(Context context, @PreferredShortcutType int shortcutType, + static void optOutValueFromSettings(Context context, @UserShortcutType int shortcutType, @NonNull ComponentName componentName) { final StringJoiner joiner = new StringJoiner(String.valueOf(COMPONENT_NAME_SEPARATOR)); final String targetKey = convertKeyFromSettings(shortcutType); @@ -226,7 +226,7 @@ final class AccessibilityUtil { * @param componentName The component name that need to be checked existed in Settings. * @return {@code true} if componentName existed in Settings. */ - static boolean hasValueInSettings(Context context, @PreferredShortcutType int shortcutType, + static boolean hasValueInSettings(Context context, @UserShortcutType int shortcutType, @NonNull ComponentName componentName) { final String targetKey = convertKeyFromSettings(shortcutType); final String targetString = Settings.Secure.getString(context.getContentResolver(), @@ -248,22 +248,22 @@ final class AccessibilityUtil { } /** - * Converts {@link PreferredShortcutType} to key in Settings. + * Converts {@link UserShortcutType} to key in Settings. * * @param shortcutType The shortcut type. * @return Mapping key in Settings. */ - static String convertKeyFromSettings(@PreferredShortcutType int shortcutType) { + static String convertKeyFromSettings(@UserShortcutType int shortcutType) { switch (shortcutType) { - case PreferredShortcutType.SOFTWARE: + case UserShortcutType.SOFTWARE: return Settings.Secure.ACCESSIBILITY_BUTTON_TARGET_COMPONENT; - case PreferredShortcutType.HARDWARE: + case UserShortcutType.HARDWARE: return Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE; - case PreferredShortcutType.TRIPLETAP: + case UserShortcutType.TRIPLETAP: return Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED; default: throw new IllegalArgumentException( - "Unsupported preferredShortcutType " + shortcutType); + "Unsupported userShortcutType " + shortcutType); } } } diff --git a/src/com/android/settings/accessibility/SharedPreferenceUtils.java b/src/com/android/settings/accessibility/SharedPreferenceUtils.java new file mode 100644 index 00000000000..b25c3d23c35 --- /dev/null +++ b/src/com/android/settings/accessibility/SharedPreferenceUtils.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.accessibility; + +import android.content.Context; +import android.content.SharedPreferences; + +import com.google.common.collect.ImmutableSet; + +import java.util.Set; + +/** Utility class for SharedPreferences. */ +public final class SharedPreferenceUtils { + + private static final String ACCESSIBILITY_PERF = "accessibility_prefs"; + private static final String USER_SHORTCUT_TYPE = "user_shortcut_type"; + private SharedPreferenceUtils() { } + + private static SharedPreferences getSharedPreferences(Context context, String fileName) { + return context.getSharedPreferences(fileName, Context.MODE_PRIVATE); + } + + /** Returns a set of user shortcuts list to determine user preferred service shortcut. */ + public static Set getUserShortcutType(Context context) { + return getSharedPreferences(context, ACCESSIBILITY_PERF) + .getStringSet(USER_SHORTCUT_TYPE, ImmutableSet.of()); + } + + /** Sets a set of user shortcuts list to determine user preferred service shortcut. */ + public static void setUserShortcutType(Context context, Set data) { + SharedPreferences.Editor editor = getSharedPreferences(context, ACCESSIBILITY_PERF).edit(); + editor.remove(USER_SHORTCUT_TYPE).apply(); + editor.putStringSet(USER_SHORTCUT_TYPE, data).apply(); + } +} diff --git a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java index bb2483300fd..e2751570fcf 100644 --- a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java @@ -35,11 +35,9 @@ import android.os.UserHandle; import android.os.storage.StorageManager; import android.provider.Settings; import android.text.TextUtils; -import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.View; -import android.view.ViewGroup; import android.view.accessibility.AccessibilityManager; import android.widget.CheckBox; @@ -47,7 +45,7 @@ import androidx.preference.PreferenceScreen; import com.android.internal.widget.LockPatternUtils; import com.android.settings.R; -import com.android.settings.accessibility.AccessibilityUtil.PreferredShortcutType; +import com.android.settings.accessibility.AccessibilityUtil.UserShortcutType; import com.android.settings.password.ConfirmDeviceCredentialActivity; import com.android.settings.widget.SwitchBar; import com.android.settings.widget.ToggleSwitch; @@ -56,19 +54,20 @@ import com.android.settingslib.accessibility.AccessibilityUtils; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.stream.Collectors; /** Fragment for providing toggle bar and basic accessibility service setup. */ public class ToggleAccessibilityServicePreferenceFragment extends ToggleFeaturePreferenceFragment implements ShortcutPreference.OnClickListener { private static final String KEY_SHORTCUT_PREFERENCE = "shortcut_preference"; - private static final String EXTRA_PREFERRED_SHORTCUT_TYPE = "preferred_shortcutType"; - // TODO(b/142530063): Check the new setting key to decide which summary should be shown. - private static final String KEY_PREFERRED_SHORTCUT_TYPE = Settings.System.MASTER_MONO; + private static final String EXTRA_SHORTCUT_TYPE = "shortcut_type"; private ShortcutPreference mShortcutPreference; - private int mPreferredShortcutType = PreferredShortcutType.DEFAULT; + private int mUserShortcutType = UserShortcutType.DEFAULT; private CheckBox mSoftwareTypeCheckBox; private CheckBox mHardwareTypeCheckBox; @@ -114,15 +113,14 @@ public class ToggleAccessibilityServicePreferenceFragment extends } @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); initShortcutPreference(savedInstanceState); - return super.onCreateView(inflater, container, savedInstanceState); } @Override public void onSaveInstanceState(Bundle outState) { - outState.putInt(EXTRA_PREFERRED_SHORTCUT_TYPE, mPreferredShortcutType); + outState.putInt(EXTRA_SHORTCUT_TYPE, mUserShortcutType); super.onSaveInstanceState(outState); } @@ -223,8 +221,8 @@ public class ToggleAccessibilityServicePreferenceFragment extends } private void updateAlertDialogCheckState() { - updateCheckStatus(mSoftwareTypeCheckBox, PreferredShortcutType.SOFTWARE); - updateCheckStatus(mHardwareTypeCheckBox, PreferredShortcutType.HARDWARE); + updateCheckStatus(mSoftwareTypeCheckBox, UserShortcutType.SOFTWARE); + updateCheckStatus(mHardwareTypeCheckBox, UserShortcutType.HARDWARE); } private void updateAlertDialogEnableState() { @@ -238,48 +236,55 @@ public class ToggleAccessibilityServicePreferenceFragment extends } } - private void updateCheckStatus(CheckBox checkBox, @PreferredShortcutType int type) { - checkBox.setChecked((mPreferredShortcutType & type) == type); + private void updateCheckStatus(CheckBox checkBox, @UserShortcutType int type) { + checkBox.setChecked((mUserShortcutType & type) == type); checkBox.setOnClickListener(v -> { - updatePreferredShortcutType(false); + updateUserShortcutType(/* saveChanges= */ false); updateAlertDialogEnableState(); }); } - private void updatePreferredShortcutType(boolean saveToDB) { - mPreferredShortcutType = PreferredShortcutType.DEFAULT; + private void updateUserShortcutType(boolean saveChanges) { + mUserShortcutType = UserShortcutType.DEFAULT; if (mSoftwareTypeCheckBox.isChecked()) { - mPreferredShortcutType |= PreferredShortcutType.SOFTWARE; + mUserShortcutType |= UserShortcutType.SOFTWARE; } if (mHardwareTypeCheckBox.isChecked()) { - mPreferredShortcutType |= PreferredShortcutType.HARDWARE; + mUserShortcutType |= UserShortcutType.HARDWARE; } - if (saveToDB) { - setPreferredShortcutType(mPreferredShortcutType); + if (saveChanges) { + setUserShortcutType(getPrefContext(), mUserShortcutType); } } - private void setSecureIntValue(String key, @PreferredShortcutType int value) { - Settings.Secure.putIntForUser(getPrefContext().getContentResolver(), - key, value, getPrefContext().getContentResolver().getUserId()); - } - - private void setPreferredShortcutType(@PreferredShortcutType int type) { - setSecureIntValue(KEY_PREFERRED_SHORTCUT_TYPE, type); + private void setUserShortcutType(Context context, int type) { + Set info = SharedPreferenceUtils.getUserShortcutType(context); + final String componentName = getComponentName().flattenToString(); + if (info.isEmpty()) { + info = new HashSet<>(); + } else { + final Set filtered = info.stream().filter( + str -> str.contains(componentName)).collect(Collectors.toSet()); + info.removeAll(filtered); + } + final AccessibilityUserShortcutType shortcut = new AccessibilityUserShortcutType( + getComponentName().flattenToString(), type); + info.add(shortcut.flattenToString()); + SharedPreferenceUtils.setUserShortcutType(context, info); } private String getShortcutTypeSummary(Context context) { - final int shortcutType = getPreferredShortcutType(context); + final int shortcutType = getUserShortcutType(context, UserShortcutType.SOFTWARE); final CharSequence softwareTitle = context.getText(AccessibilityUtil.isGestureNavigateEnabled(context) ? R.string.accessibility_shortcut_edit_dialog_title_software_gesture : R.string.accessibility_shortcut_edit_dialog_title_software); List list = new ArrayList<>(); - if ((shortcutType & PreferredShortcutType.SOFTWARE) == PreferredShortcutType.SOFTWARE) { + if ((shortcutType & UserShortcutType.SOFTWARE) == UserShortcutType.SOFTWARE) { list.add(softwareTitle); } - if ((shortcutType & PreferredShortcutType.HARDWARE) == PreferredShortcutType.HARDWARE) { + if ((shortcutType & UserShortcutType.HARDWARE) == UserShortcutType.HARDWARE) { final CharSequence hardwareTitle = context.getText( R.string.accessibility_shortcut_edit_dialog_title_hardware); list.add(hardwareTitle); @@ -293,22 +298,23 @@ public class ToggleAccessibilityServicePreferenceFragment extends return AccessibilityUtil.capitalize(joinStrings); } - @PreferredShortcutType - private int getPreferredShortcutType(Context context) { - return getSecureIntValue(context, KEY_PREFERRED_SHORTCUT_TYPE, - PreferredShortcutType.SOFTWARE); - } + private int getUserShortcutType(Context context, @UserShortcutType int defaultValue) { + final Set info = SharedPreferenceUtils.getUserShortcutType(context); + final String componentName = getComponentName().flattenToString(); + final Set filtered = info.stream().filter( + str -> str.contains(componentName)).collect( + Collectors.toSet()); + if (filtered.isEmpty()) { + return defaultValue; + } - @PreferredShortcutType - private int getSecureIntValue(Context context, String key, - @PreferredShortcutType int defaultValue) { - return Settings.Secure.getIntForUser( - context.getContentResolver(), - key, defaultValue, context.getContentResolver().getUserId()); + final String str = (String) filtered.toArray()[0]; + final AccessibilityUserShortcutType shortcut = new AccessibilityUserShortcutType(str); + return shortcut.getUserShortcutType(); } private void callOnAlertDialogCheckboxClicked(DialogInterface dialog, int which) { - updatePreferredShortcutType(true); + updateUserShortcutType(/* saveChanges= */ true); mShortcutPreference.setSummary( getShortcutTypeSummary(getPrefContext())); } @@ -340,13 +346,13 @@ public class ToggleAccessibilityServicePreferenceFragment extends } private void initShortcutPreference(Bundle savedInstanceState) { - // Restore the PreferredShortcut type - if (savedInstanceState != null) { - mPreferredShortcutType = savedInstanceState.getInt(EXTRA_PREFERRED_SHORTCUT_TYPE, - PreferredShortcutType.DEFAULT); - } - if (mPreferredShortcutType == PreferredShortcutType.DEFAULT) { - mPreferredShortcutType = getPreferredShortcutType(getPrefContext()); + mUserShortcutType = getUserShortcutType(getPrefContext(), + UserShortcutType.SOFTWARE); + + // Restore the user shortcut type + if (savedInstanceState != null && savedInstanceState.containsKey(EXTRA_SHORTCUT_TYPE)) { + mUserShortcutType = savedInstanceState.getInt(EXTRA_SHORTCUT_TYPE, + UserShortcutType.SOFTWARE); } // Initial ShortcutPreference widget @@ -370,11 +376,11 @@ public class ToggleAccessibilityServicePreferenceFragment extends getShortcutPreferenceKey()); if (shortcutPreference != null) { - // TODO(b/142531156): Replace PreferredShortcutType.SOFTWARE value with dialog shortcut + // TODO(b/142531156): Replace UserShortcutType.SOFTWARE value with dialog shortcut // preferred key. shortcutPreference.setChecked( AccessibilityUtil.hasValueInSettings(getContext(), - PreferredShortcutType.SOFTWARE, + UserShortcutType.SOFTWARE, mComponentName)); } } @@ -472,22 +478,23 @@ public class ToggleAccessibilityServicePreferenceFragment extends preference.setChecked(false); showPopupDialog(DialogType.ENABLE_WARNING_FROM_SHORTCUT); } else { - // TODO(b/142531156): Replace PreferredShortcutType.SOFTWARE value with dialog + // TODO(b/142531156): Replace UserShortcutType.SOFTWARE value with dialog // shortcut preferred key. - AccessibilityUtil.optInValueToSettings(getContext(), PreferredShortcutType.SOFTWARE, + AccessibilityUtil.optInValueToSettings(getContext(), UserShortcutType.SOFTWARE, mComponentName); } } else { - // TODO(b/142531156): Replace PreferredShortcutType.SOFTWARE value with dialog shortcut + // TODO(b/142531156): Replace UserShortcutType.SOFTWARE value with dialog shortcut // preferred key. - AccessibilityUtil.optOutValueFromSettings(getContext(), PreferredShortcutType.SOFTWARE, + AccessibilityUtil.optOutValueFromSettings(getContext(), UserShortcutType.SOFTWARE, mComponentName); } } @Override public void onSettingsClicked(ShortcutPreference preference) { - mPreferredShortcutType = getPreferredShortcutType(getPrefContext()); + mUserShortcutType = getUserShortcutType(getPrefContext(), + UserShortcutType.SOFTWARE); showPopupDialog(DialogType.EDIT_SHORTCUT); } @@ -571,9 +578,9 @@ public class ToggleAccessibilityServicePreferenceFragment extends private void onAllowButtonFromShortcutClicked() { final ShortcutPreference shortcutPreference = findPreference(getShortcutPreferenceKey()); shortcutPreference.setChecked(true); - // TODO(b/142531156): Replace PreferredShortcutType.SOFTWARE value with dialog shortcut + // TODO(b/142531156): Replace UserShortcutType.SOFTWARE value with dialog shortcut // preferred key. - AccessibilityUtil.optInValueToSettings(getContext(), PreferredShortcutType.SOFTWARE, + AccessibilityUtil.optInValueToSettings(getContext(), UserShortcutType.SOFTWARE, mComponentName); mDialog.dismiss(); @@ -615,4 +622,8 @@ public class ToggleAccessibilityServicePreferenceFragment extends false)); } } + + private ComponentName getComponentName() { + return mComponentName; + } } diff --git a/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java index c32248d8c1c..b4c7dcea277 100644 --- a/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java @@ -39,14 +39,17 @@ import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import com.android.settings.R; -import com.android.settings.accessibility.AccessibilityUtil.PreferredShortcutType; import com.android.settings.accessibility.AccessibilityUtil.State; +import com.android.settings.accessibility.AccessibilityUtil.UserShortcutType; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.widget.SwitchBar; import com.android.settingslib.search.SearchIndexable; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; /** Settings page for color inversion. */ @SearchIndexable @@ -59,13 +62,11 @@ public class ToggleColorInversionPreferenceFragment extends ToggleFeaturePrefere private static final int DIALOG_ID_EDIT_SHORTCUT = 1; private static final String DISPLAY_INVERSION_ENABLED = Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED; - private static final String EXTRA_SHORTCUT_TYPE = "shortcutType"; - // TODO(b/142530063): Check the new setting key to decide which summary should be shown. - private static final String KEY_SHORTCUT_TYPE = Settings.System.MASTER_MONO; + private static final String EXTRA_SHORTCUT_TYPE = "shortcut_type"; private final Handler mHandler = new Handler(); private ShortcutPreference mShortcutPreference; private SettingsContentObserver mSettingsContentObserver; - private int mPreferredShortcutType = PreferredShortcutType.DEFAULT; + private int mUserShortcutType = UserShortcutType.DEFAULT; private CheckBox mSoftwareTypeCheckBox; private CheckBox mHardwareTypeCheckBox; @@ -142,7 +143,7 @@ public class ToggleColorInversionPreferenceFragment extends ToggleFeaturePrefere @Override public void onSaveInstanceState(Bundle outState) { - outState.putInt(EXTRA_SHORTCUT_TYPE, mPreferredShortcutType); + outState.putInt(EXTRA_SHORTCUT_TYPE, mUserShortcutType); super.onSaveInstanceState(outState); } @@ -176,8 +177,8 @@ public class ToggleColorInversionPreferenceFragment extends ToggleFeaturePrefere } private void updateAlertDialogCheckState() { - updateCheckStatus(mSoftwareTypeCheckBox, PreferredShortcutType.SOFTWARE); - updateCheckStatus(mHardwareTypeCheckBox, PreferredShortcutType.HARDWARE); + updateCheckStatus(mSoftwareTypeCheckBox, UserShortcutType.SOFTWARE); + updateCheckStatus(mHardwareTypeCheckBox, UserShortcutType.HARDWARE); } private void updateAlertDialogEnableState() { @@ -191,48 +192,55 @@ public class ToggleColorInversionPreferenceFragment extends ToggleFeaturePrefere } } - private void updateCheckStatus(CheckBox checkBox, @PreferredShortcutType int type) { - checkBox.setChecked((mPreferredShortcutType & type) == type); + private void updateCheckStatus(CheckBox checkBox, @UserShortcutType int type) { + checkBox.setChecked((mUserShortcutType & type) == type); checkBox.setOnClickListener(v -> { - updatePreferredShortcutType(false); + updateUserShortcutType(/* saveChanges= */ false); updateAlertDialogEnableState(); }); } - private void updatePreferredShortcutType(boolean saveToDB) { - mPreferredShortcutType = PreferredShortcutType.DEFAULT; + private void updateUserShortcutType(boolean saveChanges) { + mUserShortcutType = UserShortcutType.DEFAULT; if (mSoftwareTypeCheckBox.isChecked()) { - mPreferredShortcutType |= PreferredShortcutType.SOFTWARE; + mUserShortcutType |= UserShortcutType.SOFTWARE; } if (mHardwareTypeCheckBox.isChecked()) { - mPreferredShortcutType |= PreferredShortcutType.HARDWARE; + mUserShortcutType |= UserShortcutType.HARDWARE; } - if (saveToDB) { - setPreferredShortcutType(mPreferredShortcutType); + if (saveChanges) { + setUserShortcutType(getPrefContext(), mUserShortcutType); } } - private void setSecureIntValue(String key, @PreferredShortcutType int value) { - Settings.Secure.putIntForUser(getPrefContext().getContentResolver(), - key, value, getPrefContext().getContentResolver().getUserId()); - } - - private void setPreferredShortcutType(@PreferredShortcutType int type) { - setSecureIntValue(KEY_SHORTCUT_TYPE, type); + private void setUserShortcutType(Context context, int type) { + Set info = SharedPreferenceUtils.getUserShortcutType(context); + if (info.isEmpty()) { + info = new HashSet<>(); + } else { + final Set filtered = info.stream().filter( + str -> str.contains(getComponentName().flattenToString())).collect( + Collectors.toSet()); + info.removeAll(filtered); + } + final AccessibilityUserShortcutType shortcut = new AccessibilityUserShortcutType( + getComponentName().flattenToString(), type); + info.add(shortcut.flattenToString()); + SharedPreferenceUtils.setUserShortcutType(context, info); } private String getShortcutTypeSummary(Context context) { - final int shortcutType = getPreferredShortcutType(context); + final int shortcutType = getUserShortcutType(context, UserShortcutType.SOFTWARE); final CharSequence softwareTitle = context.getText(AccessibilityUtil.isGestureNavigateEnabled(context) ? R.string.accessibility_shortcut_edit_dialog_title_software_gesture : R.string.accessibility_shortcut_edit_dialog_title_software); List list = new ArrayList<>(); - if ((shortcutType & PreferredShortcutType.SOFTWARE) == PreferredShortcutType.SOFTWARE) { + if ((shortcutType & UserShortcutType.SOFTWARE) == UserShortcutType.SOFTWARE) { list.add(softwareTitle); } - if ((shortcutType & PreferredShortcutType.HARDWARE) == PreferredShortcutType.HARDWARE) { + if ((shortcutType & UserShortcutType.HARDWARE) == UserShortcutType.HARDWARE) { final CharSequence hardwareTitle = context.getText( R.string.accessibility_shortcut_edit_dialog_title_hardware); list.add(hardwareTitle); @@ -246,21 +254,23 @@ public class ToggleColorInversionPreferenceFragment extends ToggleFeaturePrefere return AccessibilityUtil.capitalize(joinStrings); } - @PreferredShortcutType - private int getPreferredShortcutType(Context context) { - return getSecureIntValue(context, KEY_SHORTCUT_TYPE, PreferredShortcutType.SOFTWARE); - } + private int getUserShortcutType(Context context, @UserShortcutType int defaultValue) { + final Set info = SharedPreferenceUtils.getUserShortcutType(context); + final String componentName = getComponentName().flattenToString(); + final Set filtered = info.stream().filter( + str -> str.contains(componentName)).collect( + Collectors.toSet()); + if (filtered.isEmpty()) { + return defaultValue; + } - @PreferredShortcutType - private int getSecureIntValue(Context context, String key, - @PreferredShortcutType int defaultValue) { - return Settings.Secure.getIntForUser( - context.getContentResolver(), - key, defaultValue, context.getContentResolver().getUserId()); + final String str = (String) filtered.toArray()[0]; + final AccessibilityUserShortcutType shortcut = new AccessibilityUserShortcutType(str); + return shortcut.getUserShortcutType(); } private void callOnAlertDialogCheckboxClicked(DialogInterface dialog, int which) { - updatePreferredShortcutType(true); + updateUserShortcutType(/* saveChanges= */ true); mShortcutPreference.setSummary( getShortcutTypeSummary(getPrefContext())); } @@ -274,13 +284,13 @@ public class ToggleColorInversionPreferenceFragment extends ToggleFeaturePrefere } private void initShortcutPreference(Bundle savedInstanceState) { - // Restore the PreferredShortcut type - if (savedInstanceState != null) { - mPreferredShortcutType = savedInstanceState.getInt(EXTRA_SHORTCUT_TYPE, - PreferredShortcutType.DEFAULT); - } - if (mPreferredShortcutType == PreferredShortcutType.DEFAULT) { - mPreferredShortcutType = getPreferredShortcutType(getPrefContext()); + mUserShortcutType = getUserShortcutType(getPrefContext(), + UserShortcutType.SOFTWARE); + + // Restore the user shortcut type + if (savedInstanceState != null && savedInstanceState.containsKey(EXTRA_SHORTCUT_TYPE)) { + mUserShortcutType = savedInstanceState.getInt(EXTRA_SHORTCUT_TYPE, + UserShortcutType.SOFTWARE); } // Initial ShortcutPreference widget @@ -305,11 +315,11 @@ public class ToggleColorInversionPreferenceFragment extends ToggleFeaturePrefere getShortcutPreferenceKey()); if (shortcutPreference != null) { - // TODO(b/142531156): Replace PreferredShortcutType.SOFTWARE value with dialog shortcut + // TODO(b/142531156): Replace UserShortcutType.SOFTWARE value with dialog shortcut // preferred key. shortcutPreference.setChecked( AccessibilityUtil.hasValueInSettings(getContext(), - PreferredShortcutType.SOFTWARE, + UserShortcutType.SOFTWARE, getComponentName())); } } @@ -325,21 +335,22 @@ public class ToggleColorInversionPreferenceFragment extends ToggleFeaturePrefere @Override public void onCheckboxClicked(ShortcutPreference preference) { if (preference.getChecked()) { - // TODO(b/142531156): Replace PreferredShortcutType.SOFTWARE value with dialog shortcut + // TODO(b/142531156): Replace UserShortcutType.SOFTWARE value with dialog shortcut // preferred key. - AccessibilityUtil.optInValueToSettings(getContext(), PreferredShortcutType.SOFTWARE, + AccessibilityUtil.optInValueToSettings(getContext(), UserShortcutType.SOFTWARE, getComponentName()); } else { - // TODO(b/142531156): Replace PreferredShortcutType.SOFTWARE value with dialog shortcut + // TODO(b/142531156): Replace UserShortcutType.SOFTWARE value with dialog shortcut // preferred key. - AccessibilityUtil.optOutValueFromSettings(getContext(), PreferredShortcutType.SOFTWARE, + AccessibilityUtil.optOutValueFromSettings(getContext(), UserShortcutType.SOFTWARE, getComponentName()); } } @Override public void onSettingsClicked(ShortcutPreference preference) { - mPreferredShortcutType = getPreferredShortcutType(getPrefContext()); + mUserShortcutType = getUserShortcutType(getPrefContext(), + UserShortcutType.SOFTWARE); showDialog(DIALOG_ID_EDIT_SHORTCUT); } diff --git a/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java index 7a77b9197aa..12a207e0afd 100644 --- a/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java @@ -38,8 +38,8 @@ import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import com.android.settings.R; -import com.android.settings.accessibility.AccessibilityUtil.PreferredShortcutType; import com.android.settings.accessibility.AccessibilityUtil.State; +import com.android.settings.accessibility.AccessibilityUtil.UserShortcutType; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.widget.SwitchBar; import com.android.settingslib.core.AbstractPreferenceController; @@ -48,7 +48,10 @@ import com.android.settingslib.search.SearchIndexable; import com.android.settingslib.widget.RadioButtonPreference; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; @SearchIndexable public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePreferenceFragment @@ -57,14 +60,12 @@ public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePrefe private static final String ENABLED = Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED; private static final String PREFERENCE_KEY = "daltonizer_mode_deuteranomaly"; - private static final String EXTRA_SHORTCUT_TYPE = "shortcutType"; - // TODO(b/142530063): Check the new setting key to decide which summary should be shown. - private static final String KEY_SHORTCUT_TYPE = Settings.System.MASTER_MONO; + private static final String EXTRA_SHORTCUT_TYPE = "shortcut_type"; private static final String KEY_SHORTCUT_PREFERENCE = "shortcut_preference"; private static final int DIALOG_ID_EDIT_SHORTCUT = 1; private static final List sControllers = new ArrayList<>(); private ShortcutPreference mShortcutPreference; - private int mPreferredShortcutType = PreferredShortcutType.DEFAULT; + private int mUserShortcutType = UserShortcutType.DEFAULT; private CheckBox mSoftwareTypeCheckBox; private CheckBox mHardwareTypeCheckBox; @@ -99,7 +100,7 @@ public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePrefe @Override public void onSaveInstanceState(Bundle outState) { - outState.putInt(EXTRA_SHORTCUT_TYPE, mPreferredShortcutType); + outState.putInt(EXTRA_SHORTCUT_TYPE, mUserShortcutType); super.onSaveInstanceState(outState); } @@ -148,8 +149,8 @@ public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePrefe } private void updateAlertDialogCheckState() { - updateCheckStatus(mSoftwareTypeCheckBox, PreferredShortcutType.SOFTWARE); - updateCheckStatus(mHardwareTypeCheckBox, PreferredShortcutType.HARDWARE); + updateCheckStatus(mSoftwareTypeCheckBox, UserShortcutType.SOFTWARE); + updateCheckStatus(mHardwareTypeCheckBox, UserShortcutType.HARDWARE); } private void updateAlertDialogEnableState() { @@ -163,48 +164,55 @@ public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePrefe } } - private void updateCheckStatus(CheckBox checkBox, @PreferredShortcutType int type) { - checkBox.setChecked((mPreferredShortcutType & type) == type); + private void updateCheckStatus(CheckBox checkBox, @UserShortcutType int type) { + checkBox.setChecked((mUserShortcutType & type) == type); checkBox.setOnClickListener(v -> { - updatePreferredShortcutType(false); + updateUserShortcutType(/* saveChanges= */ false); updateAlertDialogEnableState(); }); } - private void updatePreferredShortcutType(boolean saveToDB) { - mPreferredShortcutType = PreferredShortcutType.DEFAULT; + private void updateUserShortcutType(boolean saveChanges) { + mUserShortcutType = UserShortcutType.DEFAULT; if (mSoftwareTypeCheckBox.isChecked()) { - mPreferredShortcutType |= PreferredShortcutType.SOFTWARE; + mUserShortcutType |= UserShortcutType.SOFTWARE; } if (mHardwareTypeCheckBox.isChecked()) { - mPreferredShortcutType |= PreferredShortcutType.HARDWARE; + mUserShortcutType |= UserShortcutType.HARDWARE; } - if (saveToDB) { - setPreferredShortcutType(mPreferredShortcutType); + if (saveChanges) { + setUserShortcutType(getPrefContext(), mUserShortcutType); } } - private void setSecureIntValue(String key, @PreferredShortcutType int value) { - Settings.Secure.putIntForUser(getPrefContext().getContentResolver(), - key, value, getPrefContext().getContentResolver().getUserId()); - } - - private void setPreferredShortcutType(@PreferredShortcutType int type) { - setSecureIntValue(KEY_SHORTCUT_TYPE, type); + private void setUserShortcutType(Context context, int type) { + Set info = SharedPreferenceUtils.getUserShortcutType(context); + if (info.isEmpty()) { + info = new HashSet<>(); + } else { + final Set filtered = info.stream().filter( + str -> str.contains(getComponentName().flattenToString())).collect( + Collectors.toSet()); + info.removeAll(filtered); + } + final AccessibilityUserShortcutType shortcut = new AccessibilityUserShortcutType( + getComponentName().flattenToString(), type); + info.add(shortcut.flattenToString()); + SharedPreferenceUtils.setUserShortcutType(context, info); } private String getShortcutTypeSummary(Context context) { - final int shortcutType = getPreferredShortcutType(context); + final int shortcutType = getUserShortcutType(context, UserShortcutType.SOFTWARE); final CharSequence softwareTitle = context.getText(AccessibilityUtil.isGestureNavigateEnabled(context) ? R.string.accessibility_shortcut_edit_dialog_title_software_gesture : R.string.accessibility_shortcut_edit_dialog_title_software); List list = new ArrayList<>(); - if ((shortcutType & PreferredShortcutType.SOFTWARE) == PreferredShortcutType.SOFTWARE) { + if ((shortcutType & UserShortcutType.SOFTWARE) == UserShortcutType.SOFTWARE) { list.add(softwareTitle); } - if ((shortcutType & PreferredShortcutType.HARDWARE) == PreferredShortcutType.HARDWARE) { + if ((shortcutType & UserShortcutType.HARDWARE) == UserShortcutType.HARDWARE) { final CharSequence hardwareTitle = context.getText( R.string.accessibility_shortcut_edit_dialog_title_hardware); list.add(hardwareTitle); @@ -218,21 +226,23 @@ public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePrefe return AccessibilityUtil.capitalize(joinStrings); } - @PreferredShortcutType - private int getPreferredShortcutType(Context context) { - return getSecureIntValue(context, KEY_SHORTCUT_TYPE, PreferredShortcutType.SOFTWARE); - } + private int getUserShortcutType(Context context, @UserShortcutType int defaultValue) { + final Set info = SharedPreferenceUtils.getUserShortcutType(context); + final String componentName = getComponentName().flattenToString(); + final Set filtered = info.stream().filter( + str -> str.contains(componentName)).collect( + Collectors.toSet()); + if (filtered.isEmpty()) { + return defaultValue; + } - @PreferredShortcutType - private int getSecureIntValue(Context context, String key, - @PreferredShortcutType int defaultValue) { - return Settings.Secure.getIntForUser( - context.getContentResolver(), - key, defaultValue, context.getContentResolver().getUserId()); + final String str = (String) filtered.toArray()[0]; + final AccessibilityUserShortcutType shortcut = new AccessibilityUserShortcutType(str); + return shortcut.getUserShortcutType(); } private void callOnAlertDialogCheckboxClicked(DialogInterface dialog, int which) { - updatePreferredShortcutType(true); + updateUserShortcutType(/* saveChanges= */ true); mShortcutPreference.setSummary( getShortcutTypeSummary(getPrefContext())); } @@ -294,32 +304,33 @@ public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePrefe @Override public void onCheckboxClicked(ShortcutPreference preference) { if (preference.getChecked()) { - // TODO(b/142531156): Replace PreferredShortcutType.SOFTWARE value with dialog shortcut + // TODO(b/142531156): Replace UserShortcutType.SOFTWARE value with dialog shortcut // preferred key. - AccessibilityUtil.optInValueToSettings(getContext(), PreferredShortcutType.SOFTWARE, + AccessibilityUtil.optInValueToSettings(getContext(), UserShortcutType.SOFTWARE, getComponentName()); } else { - // TODO(b/142531156): Replace PreferredShortcutType.SOFTWARE value with dialog shortcut + // TODO(b/142531156): Replace UserShortcutType.SOFTWARE value with dialog shortcut // preferred key. - AccessibilityUtil.optOutValueFromSettings(getContext(), PreferredShortcutType.SOFTWARE, + AccessibilityUtil.optOutValueFromSettings(getContext(), UserShortcutType.SOFTWARE, getComponentName()); } } @Override public void onSettingsClicked(ShortcutPreference preference) { - mPreferredShortcutType = getPreferredShortcutType(getPrefContext()); + mUserShortcutType = getUserShortcutType(getPrefContext(), + UserShortcutType.SOFTWARE); showDialog(DIALOG_ID_EDIT_SHORTCUT); } private void initShortcutPreference(Bundle savedInstanceState) { - // Restore the PreferredShortcut type - if (savedInstanceState != null) { - mPreferredShortcutType = savedInstanceState.getInt(EXTRA_SHORTCUT_TYPE, - PreferredShortcutType.DEFAULT); - } - if (mPreferredShortcutType == PreferredShortcutType.DEFAULT) { - mPreferredShortcutType = getPreferredShortcutType(getPrefContext()); + mUserShortcutType = getUserShortcutType(getPrefContext(), + UserShortcutType.SOFTWARE); + + // Restore the user shortcut type + if (savedInstanceState != null && savedInstanceState.containsKey(EXTRA_SHORTCUT_TYPE)) { + mUserShortcutType = savedInstanceState.getInt(EXTRA_SHORTCUT_TYPE, + UserShortcutType.SOFTWARE); } // Initial ShortcutPreference widget @@ -344,11 +355,11 @@ public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePrefe getShortcutPreferenceKey()); if (shortcutPreference != null) { - // TODO(b/142531156): Replace PreferredShortcutType.SOFTWARE value with dialog shortcut + // TODO(b/142531156): Replace UserShortcutType.SOFTWARE value with dialog shortcut // preferred key. shortcutPreference.setChecked( AccessibilityUtil.hasValueInSettings(getContext(), - PreferredShortcutType.SOFTWARE, + UserShortcutType.SOFTWARE, getComponentName())); } diff --git a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java index 094b909f444..5f1171af8f3 100644 --- a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java @@ -24,6 +24,7 @@ import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; import android.text.Html; +import android.text.TextUtils; import android.view.View; import android.widget.ImageView; @@ -38,6 +39,7 @@ import com.android.settings.widget.ToggleSwitch; import java.util.ArrayList; import java.util.List; +import java.util.StringJoiner; public abstract class ToggleFeaturePreferenceFragment extends SettingsPreferenceFragment { @@ -227,4 +229,49 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference mImageGetterCacheView.setImageDrawable(null); return drawable; } + + static final class AccessibilityUserShortcutType { + private static final char COMPONENT_NAME_SEPARATOR = ':'; + private static final TextUtils.SimpleStringSplitter sStringColonSplitter = + new TextUtils.SimpleStringSplitter(COMPONENT_NAME_SEPARATOR); + + private String mComponentName; + private int mUserShortcutType; + + AccessibilityUserShortcutType(String componentName, int userShortcutType) { + this.mComponentName = componentName; + this.mUserShortcutType = userShortcutType; + } + + AccessibilityUserShortcutType(String flattenedString) { + sStringColonSplitter.setString(flattenedString); + if (sStringColonSplitter.hasNext()) { + this.mComponentName = sStringColonSplitter.next(); + this.mUserShortcutType = Integer.parseInt(sStringColonSplitter.next()); + } + } + + String getComponentName() { + return mComponentName; + } + + void setComponentName(String componentName) { + this.mComponentName = componentName; + } + + int getUserShortcutType() { + return mUserShortcutType; + } + + void setUserShortcutType(int userShortcutType) { + this.mUserShortcutType = userShortcutType; + } + + String flattenToString() { + final StringJoiner joiner = new StringJoiner(String.valueOf(COMPONENT_NAME_SEPARATOR)); + joiner.add(mComponentName); + joiner.add(String.valueOf(mUserShortcutType)); + return joiner.toString(); + } + } } diff --git a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java index bfc23601ee1..c6756a89806 100644 --- a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java @@ -47,23 +47,24 @@ import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceViewHolder; import com.android.settings.R; -import com.android.settings.accessibility.AccessibilityUtil.PreferredShortcutType; +import com.android.settings.accessibility.AccessibilityUtil.UserShortcutType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.StringJoiner; +import java.util.stream.Collectors; public class ToggleScreenMagnificationPreferenceFragment extends ToggleFeaturePreferenceFragment implements ShortcutPreference.OnClickListener { private static final String SETTINGS_KEY = "screen_magnification_settings"; - private static final String EXTRA_SHORTCUT_TYPE = "shortcutType"; - // TODO(b/142530063): Check the new setting key to decide which summary should be shown. - private static final String KEY_SHORTCUT_TYPE = Settings.System.MASTER_MONO; + private static final String EXTRA_SHORTCUT_TYPE = "shortcut_type"; private ShortcutPreference mShortcutPreference; - private int mPreferredShortcutType = PreferredShortcutType.DEFAULT; + private int mUserShortcutType = UserShortcutType.DEFAULT; private CheckBox mSoftwareTypeCheckBox; private CheckBox mHardwareTypeCheckBox; private CheckBox mTripleTapTypeCheckBox; @@ -206,7 +207,7 @@ public class ToggleScreenMagnificationPreferenceFragment extends @Override public void onSaveInstanceState(Bundle outState) { - outState.putInt(EXTRA_SHORTCUT_TYPE, mPreferredShortcutType); + outState.putInt(EXTRA_SHORTCUT_TYPE, mUserShortcutType); super.onSaveInstanceState(outState); } @@ -263,9 +264,9 @@ public class ToggleScreenMagnificationPreferenceFragment extends } private void updateAlertDialogCheckState() { - updateCheckStatus(mSoftwareTypeCheckBox, PreferredShortcutType.SOFTWARE); - updateCheckStatus(mHardwareTypeCheckBox, PreferredShortcutType.HARDWARE); - updateCheckStatus(mTripleTapTypeCheckBox, PreferredShortcutType.TRIPLETAP); + updateCheckStatus(mSoftwareTypeCheckBox, UserShortcutType.SOFTWARE); + updateCheckStatus(mHardwareTypeCheckBox, UserShortcutType.HARDWARE); + updateCheckStatus(mTripleTapTypeCheckBox, UserShortcutType.TRIPLETAP); } private void updateAlertDialogEnableState() { @@ -282,57 +283,64 @@ public class ToggleScreenMagnificationPreferenceFragment extends } } - private void updateCheckStatus(CheckBox checkBox, @PreferredShortcutType int type) { - checkBox.setChecked((mPreferredShortcutType & type) == type); + private void updateCheckStatus(CheckBox checkBox, @UserShortcutType int type) { + checkBox.setChecked((mUserShortcutType & type) == type); checkBox.setOnClickListener(v -> { - updatePreferredShortcutType(false); + updateUserShortcutType(/* saveChanges= */ false); updateAlertDialogEnableState(); }); } - private void updatePreferredShortcutType(boolean saveToDB) { - mPreferredShortcutType = PreferredShortcutType.DEFAULT; + private void updateUserShortcutType(boolean saveChanges) { + mUserShortcutType = UserShortcutType.DEFAULT; if (mSoftwareTypeCheckBox.isChecked()) { - mPreferredShortcutType |= PreferredShortcutType.SOFTWARE; + mUserShortcutType |= UserShortcutType.SOFTWARE; } if (mHardwareTypeCheckBox.isChecked()) { - mPreferredShortcutType |= PreferredShortcutType.HARDWARE; + mUserShortcutType |= UserShortcutType.HARDWARE; } if (mTripleTapTypeCheckBox.isChecked()) { - mPreferredShortcutType |= PreferredShortcutType.TRIPLETAP; + mUserShortcutType |= UserShortcutType.TRIPLETAP; } - if (saveToDB) { - setPreferredShortcutType(mPreferredShortcutType); + if (saveChanges) { + setUserShortcutType(getPrefContext(), mUserShortcutType); } } - private void setSecureIntValue(String key, @PreferredShortcutType int value) { - Settings.Secure.putIntForUser(getPrefContext().getContentResolver(), - key, value, getPrefContext().getContentResolver().getUserId()); - } - - private void setPreferredShortcutType(@PreferredShortcutType int type) { - setSecureIntValue(KEY_SHORTCUT_TYPE, type); + private void setUserShortcutType(Context context, int type) { + Set info = SharedPreferenceUtils.getUserShortcutType(context); + if (info.isEmpty()) { + info = new HashSet<>(); + } else { + final Set filtered = info.stream().filter( + str -> str.contains(getComponentName())).collect( + Collectors.toSet()); + info.removeAll(filtered); + } + final AccessibilityUserShortcutType shortcut = new AccessibilityUserShortcutType( + getComponentName(), type); + info.add(shortcut.flattenToString()); + SharedPreferenceUtils.setUserShortcutType(context, info); } private String getShortcutTypeSummary(Context context) { - final int shortcutType = getPreferredShortcutType(context); + final int shortcutType = getUserShortcutType(context, UserShortcutType.DEFAULT); final CharSequence softwareTitle = context.getText(AccessibilityUtil.isGestureNavigateEnabled(context) ? R.string.accessibility_shortcut_edit_dialog_title_software_gesture : R.string.accessibility_shortcut_edit_dialog_title_software); List list = new ArrayList<>(); - if ((shortcutType & PreferredShortcutType.SOFTWARE) == PreferredShortcutType.SOFTWARE) { + if ((shortcutType & UserShortcutType.SOFTWARE) == UserShortcutType.SOFTWARE) { list.add(softwareTitle); } - if ((shortcutType & PreferredShortcutType.HARDWARE) == PreferredShortcutType.HARDWARE) { + if ((shortcutType & UserShortcutType.HARDWARE) == UserShortcutType.HARDWARE) { final CharSequence hardwareTitle = context.getText( R.string.accessibility_shortcut_edit_dialog_title_hardware); list.add(hardwareTitle); } - if ((shortcutType & PreferredShortcutType.TRIPLETAP) == PreferredShortcutType.TRIPLETAP) { + if ((shortcutType & UserShortcutType.TRIPLETAP) == UserShortcutType.TRIPLETAP) { final CharSequence tripleTapTitle = context.getText( R.string.accessibility_shortcut_edit_dialog_title_triple_tap); list.add(tripleTapTitle); @@ -346,25 +354,30 @@ public class ToggleScreenMagnificationPreferenceFragment extends return AccessibilityUtil.capitalize(joinStrings); } - @PreferredShortcutType - private int getPreferredShortcutType(Context context) { - return getSecureIntValue(context, KEY_SHORTCUT_TYPE, PreferredShortcutType.SOFTWARE); - } + private int getUserShortcutType(Context context, @UserShortcutType int defaultValue) { + final Set info = SharedPreferenceUtils.getUserShortcutType(context); + final Set filtered = info.stream().filter( + str -> str.contains(getComponentName())).collect( + Collectors.toSet()); + if (filtered.isEmpty()) { + return defaultValue; + } - @PreferredShortcutType - private int getSecureIntValue(Context context, String key, - @PreferredShortcutType int defaultValue) { - return Settings.Secure.getIntForUser( - context.getContentResolver(), - key, defaultValue, context.getContentResolver().getUserId()); + final String str = (String) filtered.toArray()[0]; + final AccessibilityUserShortcutType shortcut = new AccessibilityUserShortcutType(str); + return shortcut.getUserShortcutType(); } private void callOnAlertDialogCheckboxClicked(DialogInterface dialog, int which) { - updatePreferredShortcutType(true); + updateUserShortcutType(/* saveChanges= */ true); mShortcutPreference.setSummary( getShortcutTypeSummary(getPrefContext())); } + private String getComponentName() { + return MAGNIFICATION_CONTROLLER_NAME; + } + @Override public int getMetricsCategory() { // TODO: Distinguish between magnification modes @@ -423,28 +436,28 @@ public class ToggleScreenMagnificationPreferenceFragment extends @Override public void onCheckboxClicked(ShortcutPreference preference) { if (preference.getChecked()) { - // TODO(b/142531156): Replace PreferredShortcutType.SOFTWARE value with dialog shortcut + // TODO(b/142531156): Replace UserShortcutType.SOFTWARE value with dialog shortcut // preferred key. - optInMagnificationValueToSettings(getContext(), PreferredShortcutType.SOFTWARE); + optInMagnificationValueToSettings(getContext(), UserShortcutType.SOFTWARE); // TODO(b/142531156): ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED need to be treated // as special case in this file. - if ((mPreferredShortcutType & PreferredShortcutType.SOFTWARE) - == PreferredShortcutType.SOFTWARE) { + if ((mUserShortcutType & UserShortcutType.SOFTWARE) + == UserShortcutType.SOFTWARE) { MagnificationPreferenceFragment.setChecked(getContentResolver(), Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED, /* isChecked= */ true); } - if ((mPreferredShortcutType & PreferredShortcutType.TRIPLETAP) - == PreferredShortcutType.TRIPLETAP) { + if ((mUserShortcutType & UserShortcutType.TRIPLETAP) + == UserShortcutType.TRIPLETAP) { MagnificationPreferenceFragment.setChecked(getContentResolver(), Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, /* isChecked= */ true); } } else { - // TODO(b/142531156): Replace PreferredShortcutType.SOFTWARE value with dialog shortcut + // TODO(b/142531156): Replace UserShortcutType.SOFTWARE value with dialog shortcut // preferred key. - optOutMagnificationValueFromSettings(getContext(), PreferredShortcutType.SOFTWARE); + optOutMagnificationValueFromSettings(getContext(), UserShortcutType.SOFTWARE); // TODO(b/142531156): ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED need to be treated // as special case in this file. @@ -459,18 +472,19 @@ public class ToggleScreenMagnificationPreferenceFragment extends @Override public void onSettingsClicked(ShortcutPreference preference) { - mPreferredShortcutType = getPreferredShortcutType(getPrefContext()); + mUserShortcutType = getUserShortcutType(getPrefContext(), + UserShortcutType.SOFTWARE); showDialog(DialogType.EDIT_SHORTCUT); } private void initShortcutPreference(Bundle savedInstanceState) { - // Restore the PreferredShortcut type - if (savedInstanceState != null) { - mPreferredShortcutType = savedInstanceState.getInt(EXTRA_SHORTCUT_TYPE, - PreferredShortcutType.DEFAULT); - } - if (mPreferredShortcutType == PreferredShortcutType.DEFAULT) { - mPreferredShortcutType = getPreferredShortcutType(getPrefContext()); + mUserShortcutType = getUserShortcutType(getPrefContext(), + UserShortcutType.SOFTWARE); + + // Restore the user shortcut type + if (savedInstanceState != null && savedInstanceState.containsKey(EXTRA_SHORTCUT_TYPE)) { + mUserShortcutType = savedInstanceState.getInt(EXTRA_SHORTCUT_TYPE, + UserShortcutType.SOFTWARE); } // Initial ShortcutPreference widget @@ -491,11 +505,11 @@ public class ToggleScreenMagnificationPreferenceFragment extends getShortcutPreferenceKey()); if (shortcutPreference != null) { - // TODO(b/142531156): Replace PreferredShortcutType.SOFTWARE value with dialog shortcut + // TODO(b/142531156): Replace UserShortcutType.SOFTWARE value with dialog shortcut // preferred key. shortcutPreference.setChecked( hasMagnificationValueInSettings(getContext(), - PreferredShortcutType.SOFTWARE)); + UserShortcutType.SOFTWARE)); } } @@ -521,7 +535,7 @@ public class ToggleScreenMagnificationPreferenceFragment extends } private static void optInMagnificationValueToSettings(Context context, - @PreferredShortcutType int shortcutType) { + @UserShortcutType int shortcutType) { final String targetKey = AccessibilityUtil.convertKeyFromSettings(shortcutType); final String targetString = Settings.Secure.getString(context.getContentResolver(), targetKey); @@ -543,7 +557,7 @@ public class ToggleScreenMagnificationPreferenceFragment extends } private static void optOutMagnificationValueFromSettings(Context context, - @PreferredShortcutType int shortcutType) { + @UserShortcutType int shortcutType) { final StringJoiner joiner = new StringJoiner(String.valueOf(COMPONENT_NAME_SEPARATOR)); final String targetKey = AccessibilityUtil.convertKeyFromSettings(shortcutType); final String targetString = Settings.Secure.getString(context.getContentResolver(), @@ -566,7 +580,7 @@ public class ToggleScreenMagnificationPreferenceFragment extends } private static boolean hasMagnificationValueInSettings(Context context, - @PreferredShortcutType int shortcutType) { + @UserShortcutType int shortcutType) { final String targetKey = AccessibilityUtil.convertKeyFromSettings(shortcutType); final String targetString = Settings.Secure.getString(context.getContentResolver(), targetKey); diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityUtilTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityUtilTest.java index 89ad8120d90..152ba22a1ec 100644 --- a/tests/robotests/src/com/android/settings/accessibility/AccessibilityUtilTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityUtilTest.java @@ -28,7 +28,7 @@ import android.os.Build; import android.provider.Settings; import com.android.settings.R; -import com.android.settings.accessibility.AccessibilityUtil.PreferredShortcutType; +import com.android.settings.accessibility.AccessibilityUtil.UserShortcutType; import org.junit.Before; import org.junit.Test; @@ -136,14 +136,14 @@ public final class AccessibilityUtilTest { public void hasValueInSettings_dummyComponentName_hasValue() { putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, DUMMY_COMPONENT_NAME.flattenToString()); - assertThat(AccessibilityUtil.hasValueInSettings(mContext, PreferredShortcutType.SOFTWARE, + assertThat(AccessibilityUtil.hasValueInSettings(mContext, UserShortcutType.SOFTWARE, DUMMY_COMPONENT_NAME)).isTrue(); } @Test public void optInValueToSettings_optInDummyComponentName2_haveDummyComponentName2String() { putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, DUMMY_COMPONENT_NAME.flattenToString()); - AccessibilityUtil.optInValueToSettings(mContext, PreferredShortcutType.SOFTWARE, + AccessibilityUtil.optInValueToSettings(mContext, UserShortcutType.SOFTWARE, DUMMY_COMPONENT_NAME2); assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEqualTo( @@ -154,9 +154,9 @@ public final class AccessibilityUtilTest { @Test public void optInValueToSettings_optInTwoDummyComponentName_haveOneDummyComponentName2String() { putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, DUMMY_COMPONENT_NAME.flattenToString()); - AccessibilityUtil.optInValueToSettings(mContext, PreferredShortcutType.SOFTWARE, + AccessibilityUtil.optInValueToSettings(mContext, UserShortcutType.SOFTWARE, DUMMY_COMPONENT_NAME2); - AccessibilityUtil.optInValueToSettings(mContext, PreferredShortcutType.SOFTWARE, + AccessibilityUtil.optInValueToSettings(mContext, UserShortcutType.SOFTWARE, DUMMY_COMPONENT_NAME2); assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEqualTo( @@ -167,7 +167,7 @@ public final class AccessibilityUtilTest { @Test public void optOutValueFromSettings_optOutDummyComponentName_emptyValue() { putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, DUMMY_COMPONENT_NAME.flattenToString()); - AccessibilityUtil.optOutValueFromSettings(mContext, PreferredShortcutType.SOFTWARE, + AccessibilityUtil.optOutValueFromSettings(mContext, UserShortcutType.SOFTWARE, DUMMY_COMPONENT_NAME); assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEmpty(); @@ -177,7 +177,7 @@ public final class AccessibilityUtilTest { public void optOutValueFromSettings_optOutDummyComponentName2_haveDummyComponentName() { putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, DUMMY_COMPONENT_NAME.flattenToString() + ":" + DUMMY_COMPONENT_NAME2.flattenToString()); - AccessibilityUtil.optOutValueFromSettings(mContext, PreferredShortcutType.SOFTWARE, + AccessibilityUtil.optOutValueFromSettings(mContext, UserShortcutType.SOFTWARE, DUMMY_COMPONENT_NAME2); assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEqualTo( diff --git a/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java index c9ca772ce46..9bebc9acea6 100644 --- a/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java @@ -16,6 +16,8 @@ package com.android.settings.accessibility; +import static com.google.common.truth.Truth.assertThat; + import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; @@ -29,6 +31,7 @@ import androidx.annotation.XmlRes; import androidx.fragment.app.FragmentActivity; import com.android.settings.R; +import com.android.settings.accessibility.ToggleFeaturePreferenceFragment.AccessibilityUserShortcutType; import com.android.settings.widget.SwitchBar; import org.junit.Test; @@ -36,11 +39,77 @@ import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; import org.robolectric.shadows.androidx.fragment.FragmentController; +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; + @RunWith(RobolectricTestRunner.class) public class ToggleFeaturePreferenceFragmentTest { private ToggleFeaturePreferenceFragmentTestable mFragment; + private static final String TEST_SERVICE_KEY_1 = "abc:111"; + private static final String TEST_SERVICE_KEY_2 = "mno:222"; + private static final String TEST_SERVICE_KEY_3 = "xyz:333"; + + private static final String TEST_SERVICE_NAME_1 = "abc"; + private static final int TEST_SERVICE_VALUE_1 = 111; + + @Test + public void a11yUserShortcutType_setConcatString_shouldReturnTargetValue() { + final AccessibilityUserShortcutType shortcut = new AccessibilityUserShortcutType( + TEST_SERVICE_KEY_1); + + assertThat(shortcut.getComponentName()).isEqualTo(TEST_SERVICE_NAME_1); + assertThat(shortcut.getUserShortcutType()).isEqualTo(TEST_SERVICE_VALUE_1); + } + + @Test + public void a11yUserShortcutType_shouldUpdateConcatString() { + final AccessibilityUserShortcutType shortcut = new AccessibilityUserShortcutType( + TEST_SERVICE_KEY_2); + + shortcut.setComponentName(TEST_SERVICE_NAME_1); + shortcut.setUserShortcutType(TEST_SERVICE_VALUE_1); + + assertThat(shortcut.flattenToString()).isEqualTo(TEST_SERVICE_KEY_1); + } + + @Test + public void stringSet_convertA11yPreferredShortcut_shouldRemoveTarget() { + Set mySet = new HashSet<>(); + mySet.add(TEST_SERVICE_KEY_1); + mySet.add(TEST_SERVICE_KEY_2); + mySet.add(TEST_SERVICE_KEY_3); + + final Set filtered = mySet.stream().filter( + str -> str.contains(TEST_SERVICE_NAME_1)).collect( + Collectors.toSet()); + mySet.removeAll(filtered); + + assertThat(mySet).doesNotContain(TEST_SERVICE_KEY_1); + assertThat(mySet).hasSize(/* expectedSize= */2); + } + + @Test + public void stringSet_convertA11yUserShortcutType_shouldReturnPreferredShortcut() { + int type = 0; + Set mySet = new HashSet<>(); + mySet.add(TEST_SERVICE_KEY_1); + mySet.add(TEST_SERVICE_KEY_2); + mySet.add(TEST_SERVICE_KEY_3); + + final Set filtered = mySet.stream().filter( + str -> str.contains(TEST_SERVICE_NAME_1)).collect( + Collectors.toSet()); + for (String str : filtered) { + final AccessibilityUserShortcutType shortcut = new AccessibilityUserShortcutType(str); + type = shortcut.getUserShortcutType(); + } + + assertThat(type).isEqualTo(TEST_SERVICE_VALUE_1); + } + @Test public void createFragment_shouldOnlyAddPreferencesOnce() { mFragment = spy(new ToggleFeaturePreferenceFragmentTestable());