diff --git a/src/com/android/settings/accessibility/AccessibilityUtil.java b/src/com/android/settings/accessibility/AccessibilityUtil.java index 4b3a3419b99..371afa1917c 100644 --- a/src/com/android/settings/accessibility/AccessibilityUtil.java +++ b/src/com/android/settings/accessibility/AccessibilityUtil.java @@ -19,16 +19,20 @@ package com.android.settings.accessibility; import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL; import android.accessibilityservice.AccessibilityServiceInfo; +import android.content.ComponentName; import android.content.Context; import android.os.Build; import android.provider.Settings; +import android.text.TextUtils; import androidx.annotation.IntDef; +import androidx.annotation.NonNull; import com.android.settings.R; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.StringJoiner; /** Provides utility methods to accessibility settings only. */ final class AccessibilityUtil { @@ -56,6 +60,12 @@ final class AccessibilityUtil { int INTUITIVE = 2; } + // TODO(b/147021230): Will move common functions and variables to + // android/internal/accessibility folder + private static final char COMPONENT_NAME_SEPARATOR = ':'; + private static final TextUtils.SimpleStringSplitter sStringColonSplitter = + new TextUtils.SimpleStringSplitter(COMPONENT_NAME_SEPARATOR); + /** * Annotation for different shortcut type UI type. * @@ -69,14 +79,14 @@ final class AccessibilityUtil { */ @Retention(RetentionPolicy.SOURCE) @IntDef({ - ShortcutType.DEFAULT, - ShortcutType.SOFTWARE, - ShortcutType.HARDWARE, - ShortcutType.TRIPLETAP, + PreferredShortcutType.DEFAULT, + PreferredShortcutType.SOFTWARE, + PreferredShortcutType.HARDWARE, + PreferredShortcutType.TRIPLETAP, }) /** Denotes the shortcut type. */ - public @interface ShortcutType { + public @interface PreferredShortcutType { int DEFAULT = 0; int SOFTWARE = 1; // 1 << 0 int HARDWARE = 2; // 1 << 1 @@ -129,7 +139,7 @@ final class AccessibilityUtil { } /** - * Gets the corresponding fragment type of a given accessibility service + * Gets the corresponding fragment type of a given accessibility service. * * @param accessibilityServiceInfo The accessibilityService's info * @return int from {@link AccessibilityServiceFragmentType} @@ -148,4 +158,112 @@ final class AccessibilityUtil { ? AccessibilityServiceFragmentType.INVISIBLE : AccessibilityServiceFragmentType.INTUITIVE; } + + /** + * Opts in component name into colon-separated {@code shortcutType} key's string in Settings. + * + * @param context The current context. + * @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, + @NonNull ComponentName componentName) { + final String targetKey = convertKeyFromSettings(shortcutType); + final String targetString = Settings.Secure.getString(context.getContentResolver(), + targetKey); + + if (TextUtils.isEmpty(targetString)) { + return; + } + + if (hasValueInSettings(context, shortcutType, componentName)) { + return; + } + + final StringJoiner joiner = new StringJoiner(String.valueOf(COMPONENT_NAME_SEPARATOR)); + + joiner.add(targetString); + joiner.add(componentName.flattenToString()); + + Settings.Secure.putString(context.getContentResolver(), targetKey, joiner.toString()); + } + + /** + * Opts out component name into colon-separated {@code shortcutType} key's string in Settings. + * + * @param context The current context. + * @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, + @NonNull ComponentName componentName) { + final StringJoiner joiner = new StringJoiner(String.valueOf(COMPONENT_NAME_SEPARATOR)); + final String targetKey = convertKeyFromSettings(shortcutType); + final String targetString = Settings.Secure.getString(context.getContentResolver(), + targetKey); + + if (TextUtils.isEmpty(targetString)) { + return; + } + + sStringColonSplitter.setString(targetString); + while (sStringColonSplitter.hasNext()) { + final String name = sStringColonSplitter.next(); + if (TextUtils.isEmpty(name) || (componentName.flattenToString()).equals(name)) { + continue; + } + joiner.add(name); + } + + Settings.Secure.putString(context.getContentResolver(), targetKey, joiner.toString()); + } + + /** + * Returns if component name existed in Settings. + * + * @param context The current context. + * @param shortcutType The preferred shortcut type user selected. + * @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, + @NonNull ComponentName componentName) { + final String targetKey = convertKeyFromSettings(shortcutType); + final String targetString = Settings.Secure.getString(context.getContentResolver(), + targetKey); + + if (TextUtils.isEmpty(targetString)) { + return false; + } + + sStringColonSplitter.setString(targetString); + + while (sStringColonSplitter.hasNext()) { + final String name = sStringColonSplitter.next(); + if ((componentName.flattenToString()).equals(name)) { + return true; + } + } + return false; + } + + /** + * Converts {@link PreferredShortcutType} to key in Settings. + * + * @param shortcutType The shortcut type. + * @return Mapping key in Settings. + */ + static String convertKeyFromSettings(@PreferredShortcutType int shortcutType) { + switch (shortcutType) { + case PreferredShortcutType.SOFTWARE: + return Settings.Secure.ACCESSIBILITY_BUTTON_TARGET_COMPONENT; + case PreferredShortcutType.HARDWARE: + return Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE; + case PreferredShortcutType.TRIPLETAP: + return Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED; + default: + throw new IllegalArgumentException( + "Unsupported preferredShortcutType " + shortcutType); + } + } } diff --git a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java index 269bc0479fe..e53154abf69 100644 --- a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java @@ -47,7 +47,7 @@ import androidx.preference.PreferenceScreen; import com.android.internal.widget.LockPatternUtils; import com.android.settings.R; -import com.android.settings.accessibility.AccessibilityUtil.ShortcutType; +import com.android.settings.accessibility.AccessibilityUtil.PreferredShortcutType; import com.android.settings.password.ConfirmDeviceCredentialActivity; import com.android.settings.widget.SwitchBar; import com.android.settings.widget.ToggleSwitch; @@ -64,11 +64,11 @@ public class ToggleAccessibilityServicePreferenceFragment extends ToggleFeaturePreferenceFragment implements ShortcutPreference.OnClickListener { private static final String KEY_SHORTCUT_PREFERENCE = "shortcut_preference"; - private static final String EXTRA_SHORTCUT_TYPE = "shortcutType"; + 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_SHORTCUT_TYPE = Settings.System.MASTER_MONO; + private static final String KEY_PREFERRED_SHORTCUT_TYPE = Settings.System.MASTER_MONO; private ShortcutPreference mShortcutPreference; - private int mShortcutType = ShortcutType.DEFAULT; + private int mPreferredShortcutType = PreferredShortcutType.DEFAULT; private CheckBox mSoftwareTypeCheckBox; private CheckBox mHardwareTypeCheckBox; @@ -136,15 +136,16 @@ public class ToggleAccessibilityServicePreferenceFragment extends @Override public void onSaveInstanceState(Bundle outState) { - outState.putInt(EXTRA_SHORTCUT_TYPE, mShortcutType); + outState.putInt(EXTRA_PREFERRED_SHORTCUT_TYPE, mPreferredShortcutType); super.onSaveInstanceState(outState); } @Override public void onResume() { + super.onResume(); mSettingsContentObserver.register(getContentResolver()); updateSwitchBarToggleSwitch(); - super.onResume(); + updateShortcutPreference(); } @Override @@ -225,8 +226,8 @@ public class ToggleAccessibilityServicePreferenceFragment extends } private void updateAlertDialogCheckState() { - updateCheckStatus(mSoftwareTypeCheckBox, ShortcutType.SOFTWARE); - updateCheckStatus(mHardwareTypeCheckBox, ShortcutType.HARDWARE); + updateCheckStatus(mSoftwareTypeCheckBox, PreferredShortcutType.SOFTWARE); + updateCheckStatus(mHardwareTypeCheckBox, PreferredShortcutType.HARDWARE); } private void updateAlertDialogEnableState() { @@ -240,48 +241,48 @@ public class ToggleAccessibilityServicePreferenceFragment extends } } - private void updateCheckStatus(CheckBox checkBox, @ShortcutType int type) { - checkBox.setChecked((mShortcutType & type) == type); + private void updateCheckStatus(CheckBox checkBox, @PreferredShortcutType int type) { + checkBox.setChecked((mPreferredShortcutType & type) == type); checkBox.setOnClickListener(v -> { - updateShortcutType(false); + updatePreferredShortcutType(false); updateAlertDialogEnableState(); }); } - private void updateShortcutType(boolean saveToDB) { - mShortcutType = ShortcutType.DEFAULT; + private void updatePreferredShortcutType(boolean saveToDB) { + mPreferredShortcutType = PreferredShortcutType.DEFAULT; if (mSoftwareTypeCheckBox.isChecked()) { - mShortcutType |= ShortcutType.SOFTWARE; + mPreferredShortcutType |= PreferredShortcutType.SOFTWARE; } if (mHardwareTypeCheckBox.isChecked()) { - mShortcutType |= ShortcutType.HARDWARE; + mPreferredShortcutType |= PreferredShortcutType.HARDWARE; } if (saveToDB) { - setShortcutType(mShortcutType); + setPreferredShortcutType(mPreferredShortcutType); } } - private void setSecureIntValue(String key, @ShortcutType int value) { + private void setSecureIntValue(String key, @PreferredShortcutType int value) { Settings.Secure.putIntForUser(getPrefContext().getContentResolver(), key, value, getPrefContext().getContentResolver().getUserId()); } - private void setShortcutType(@ShortcutType int type) { - setSecureIntValue(KEY_SHORTCUT_TYPE, type); + private void setPreferredShortcutType(@PreferredShortcutType int type) { + setSecureIntValue(KEY_PREFERRED_SHORTCUT_TYPE, type); } private String getShortcutTypeSummary(Context context) { - final int shortcutType = getShortcutType(context); + final int shortcutType = getPreferredShortcutType(context); 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 & ShortcutType.SOFTWARE) == ShortcutType.SOFTWARE) { + if ((shortcutType & PreferredShortcutType.SOFTWARE) == PreferredShortcutType.SOFTWARE) { list.add(softwareTitle); } - if ((shortcutType & ShortcutType.HARDWARE) == ShortcutType.HARDWARE) { + if ((shortcutType & PreferredShortcutType.HARDWARE) == PreferredShortcutType.HARDWARE) { final CharSequence hardwareTitle = context.getText( R.string.accessibility_shortcut_edit_dialog_title_hardware); list.add(hardwareTitle); @@ -295,20 +296,22 @@ public class ToggleAccessibilityServicePreferenceFragment extends return AccessibilityUtil.capitalize(joinStrings); } - @ShortcutType - private int getShortcutType(Context context) { - return getSecureIntValue(context, KEY_SHORTCUT_TYPE, ShortcutType.SOFTWARE); + @PreferredShortcutType + private int getPreferredShortcutType(Context context) { + return getSecureIntValue(context, KEY_PREFERRED_SHORTCUT_TYPE, + PreferredShortcutType.SOFTWARE); } - @ShortcutType - private int getSecureIntValue(Context context, String key, @ShortcutType int defaultValue) { + @PreferredShortcutType + private int getSecureIntValue(Context context, String key, + @PreferredShortcutType int defaultValue) { return Settings.Secure.getIntForUser( context.getContentResolver(), key, defaultValue, context.getContentResolver().getUserId()); } private void callOnAlertDialogCheckboxClicked(DialogInterface dialog, int which) { - updateShortcutType(true); + updatePreferredShortcutType(true); mShortcutPreference.setSummary( getShortcutTypeSummary(getPrefContext())); } @@ -339,12 +342,13 @@ public class ToggleAccessibilityServicePreferenceFragment extends } private void initShortcutPreference(Bundle savedInstanceState) { - // Restore the Shortcut type + // Restore the PreferredShortcut type if (savedInstanceState != null) { - mShortcutType = savedInstanceState.getInt(EXTRA_SHORTCUT_TYPE, ShortcutType.DEFAULT); + mPreferredShortcutType = savedInstanceState.getInt(EXTRA_PREFERRED_SHORTCUT_TYPE, + PreferredShortcutType.DEFAULT); } - if (mShortcutType == ShortcutType.DEFAULT) { - mShortcutType = getShortcutType(getPrefContext()); + if (mPreferredShortcutType == PreferredShortcutType.DEFAULT) { + mPreferredShortcutType = getPreferredShortcutType(getPrefContext()); } // Initial ShortcutPreference widget @@ -353,17 +357,31 @@ public class ToggleAccessibilityServicePreferenceFragment extends preferenceScreen.getContext(), null); mShortcutPreference.setPersistent(false); mShortcutPreference.setKey(getShortcutPreferenceKey()); - mShortcutPreference.setOrder(-1); mShortcutPreference.setTitle(R.string.accessibility_shortcut_title); - mShortcutPreference.setOnClickListener(this); mShortcutPreference.setSummary(getShortcutTypeSummary(getPrefContext())); + mShortcutPreference.setOnClickListener(this); // Put the shortcutPreference before settingsPreference. mShortcutPreference.setOrder(-1); - preferenceScreen.addPreference(mShortcutPreference); // TODO(b/142530063): Check the new key to decide whether checkbox should be checked. + preferenceScreen.addPreference(mShortcutPreference); } - public String getShortcutPreferenceKey() { + private void updateShortcutPreference() { + final PreferenceScreen preferenceScreen = getPreferenceScreen(); + ShortcutPreference shortcutPreference = preferenceScreen.findPreference( + getShortcutPreferenceKey()); + + if (shortcutPreference != null) { + // TODO(b/142531156): Replace PreferredShortcutType.SOFTWARE value with dialog shortcut + // preferred key. + shortcutPreference.setChecked( + AccessibilityUtil.hasValueInSettings(getContext(), + PreferredShortcutType.SOFTWARE, + mComponentName)); + } + } + + protected String getShortcutPreferenceKey() { return KEY_SHORTCUT_PREFERENCE; } @@ -464,15 +482,21 @@ public class ToggleAccessibilityServicePreferenceFragment extends @Override public void onCheckboxClicked(ShortcutPreference preference) { if (preference.getChecked()) { - // TODO(b/142530063): Enable shortcut when checkbox is checked. + // TODO(b/142531156): Replace PreferredShortcutType.SOFTWARE value with dialog shortcut + // preferred key. + AccessibilityUtil.optInValueToSettings(getContext(), PreferredShortcutType.SOFTWARE, + mComponentName); } else { - // TODO(b/142530063): Disable shortcut when checkbox is unchecked. + // TODO(b/142531156): Replace PreferredShortcutType.SOFTWARE value with dialog shortcut + // preferred key. + AccessibilityUtil.optOutValueFromSettings(getContext(), PreferredShortcutType.SOFTWARE, + mComponentName); } } @Override public void onSettingsClicked(ShortcutPreference preference) { - mShortcutType = getShortcutType(getPrefContext()); + mPreferredShortcutType = getPreferredShortcutType(getPrefContext()); showDialog(DialogType.EDIT_SHORTCUT); } diff --git a/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java index 1c7a5f30a5a..c32248d8c1c 100644 --- a/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleColorInversionPreferenceFragment.java @@ -16,8 +16,11 @@ package com.android.settings.accessibility; +import static com.android.internal.accessibility.AccessibilityShortcutController.COLOR_INVERSION_COMPONENT_NAME; + import android.app.Dialog; import android.app.settings.SettingsEnums; +import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; import android.net.Uri; @@ -36,7 +39,7 @@ import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import com.android.settings.R; -import com.android.settings.accessibility.AccessibilityUtil.ShortcutType; +import com.android.settings.accessibility.AccessibilityUtil.PreferredShortcutType; import com.android.settings.accessibility.AccessibilityUtil.State; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.widget.SwitchBar; @@ -62,7 +65,7 @@ public class ToggleColorInversionPreferenceFragment extends ToggleFeaturePrefere private final Handler mHandler = new Handler(); private ShortcutPreference mShortcutPreference; private SettingsContentObserver mSettingsContentObserver; - private int mShortcutType = ShortcutType.DEFAULT; + private int mPreferredShortcutType = PreferredShortcutType.DEFAULT; private CheckBox mSoftwareTypeCheckBox; private CheckBox mHardwareTypeCheckBox; @@ -139,10 +142,16 @@ public class ToggleColorInversionPreferenceFragment extends ToggleFeaturePrefere @Override public void onSaveInstanceState(Bundle outState) { - outState.putInt(EXTRA_SHORTCUT_TYPE, mShortcutType); + outState.putInt(EXTRA_SHORTCUT_TYPE, mPreferredShortcutType); super.onSaveInstanceState(outState); } + @Override + public void onResume() { + super.onResume(); + updateShortcutPreference(); + } + @Override public Dialog onCreateDialog(int dialogId) { if (dialogId == DIALOG_ID_EDIT_SHORTCUT) { @@ -167,8 +176,8 @@ public class ToggleColorInversionPreferenceFragment extends ToggleFeaturePrefere } private void updateAlertDialogCheckState() { - updateCheckStatus(mSoftwareTypeCheckBox, ShortcutType.SOFTWARE); - updateCheckStatus(mHardwareTypeCheckBox, ShortcutType.HARDWARE); + updateCheckStatus(mSoftwareTypeCheckBox, PreferredShortcutType.SOFTWARE); + updateCheckStatus(mHardwareTypeCheckBox, PreferredShortcutType.HARDWARE); } private void updateAlertDialogEnableState() { @@ -182,48 +191,48 @@ public class ToggleColorInversionPreferenceFragment extends ToggleFeaturePrefere } } - private void updateCheckStatus(CheckBox checkBox, @ShortcutType int type) { - checkBox.setChecked((mShortcutType & type) == type); + private void updateCheckStatus(CheckBox checkBox, @PreferredShortcutType int type) { + checkBox.setChecked((mPreferredShortcutType & type) == type); checkBox.setOnClickListener(v -> { - updateShortcutType(false); + updatePreferredShortcutType(false); updateAlertDialogEnableState(); }); } - private void updateShortcutType(boolean saveToDB) { - mShortcutType = ShortcutType.DEFAULT; + private void updatePreferredShortcutType(boolean saveToDB) { + mPreferredShortcutType = PreferredShortcutType.DEFAULT; if (mSoftwareTypeCheckBox.isChecked()) { - mShortcutType |= ShortcutType.SOFTWARE; + mPreferredShortcutType |= PreferredShortcutType.SOFTWARE; } if (mHardwareTypeCheckBox.isChecked()) { - mShortcutType |= ShortcutType.HARDWARE; + mPreferredShortcutType |= PreferredShortcutType.HARDWARE; } if (saveToDB) { - setShortcutType(mShortcutType); + setPreferredShortcutType(mPreferredShortcutType); } } - private void setSecureIntValue(String key, @ShortcutType int value) { + private void setSecureIntValue(String key, @PreferredShortcutType int value) { Settings.Secure.putIntForUser(getPrefContext().getContentResolver(), key, value, getPrefContext().getContentResolver().getUserId()); } - private void setShortcutType(@ShortcutType int type) { + private void setPreferredShortcutType(@PreferredShortcutType int type) { setSecureIntValue(KEY_SHORTCUT_TYPE, type); } private String getShortcutTypeSummary(Context context) { - final int shortcutType = getShortcutType(context); + final int shortcutType = getPreferredShortcutType(context); 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 & ShortcutType.SOFTWARE) == ShortcutType.SOFTWARE) { + if ((shortcutType & PreferredShortcutType.SOFTWARE) == PreferredShortcutType.SOFTWARE) { list.add(softwareTitle); } - if ((shortcutType & ShortcutType.HARDWARE) == ShortcutType.HARDWARE) { + if ((shortcutType & PreferredShortcutType.HARDWARE) == PreferredShortcutType.HARDWARE) { final CharSequence hardwareTitle = context.getText( R.string.accessibility_shortcut_edit_dialog_title_hardware); list.add(hardwareTitle); @@ -237,20 +246,21 @@ public class ToggleColorInversionPreferenceFragment extends ToggleFeaturePrefere return AccessibilityUtil.capitalize(joinStrings); } - @ShortcutType - private int getShortcutType(Context context) { - return getSecureIntValue(context, KEY_SHORTCUT_TYPE, ShortcutType.SOFTWARE); + @PreferredShortcutType + private int getPreferredShortcutType(Context context) { + return getSecureIntValue(context, KEY_SHORTCUT_TYPE, PreferredShortcutType.SOFTWARE); } - @ShortcutType - private int getSecureIntValue(Context context, String key, @ShortcutType int defaultValue) { + @PreferredShortcutType + private int getSecureIntValue(Context context, String key, + @PreferredShortcutType int defaultValue) { return Settings.Secure.getIntForUser( context.getContentResolver(), key, defaultValue, context.getContentResolver().getUserId()); } private void callOnAlertDialogCheckboxClicked(DialogInterface dialog, int which) { - updateShortcutType(true); + updatePreferredShortcutType(true); mShortcutPreference.setSummary( getShortcutTypeSummary(getPrefContext())); } @@ -264,12 +274,13 @@ public class ToggleColorInversionPreferenceFragment extends ToggleFeaturePrefere } private void initShortcutPreference(Bundle savedInstanceState) { - // Restore the Shortcut type + // Restore the PreferredShortcut type if (savedInstanceState != null) { - mShortcutType = savedInstanceState.getInt(EXTRA_SHORTCUT_TYPE, ShortcutType.DEFAULT); + mPreferredShortcutType = savedInstanceState.getInt(EXTRA_SHORTCUT_TYPE, + PreferredShortcutType.DEFAULT); } - if (mShortcutType == ShortcutType.DEFAULT) { - mShortcutType = getShortcutType(getPrefContext()); + if (mPreferredShortcutType == PreferredShortcutType.DEFAULT) { + mPreferredShortcutType = getPreferredShortcutType(getPrefContext()); } // Initial ShortcutPreference widget @@ -277,33 +288,58 @@ public class ToggleColorInversionPreferenceFragment extends ToggleFeaturePrefere mShortcutPreference = new ShortcutPreference( preferenceScreen.getContext(), null); final Preference previewPreference = findPreference(PREVIEW_PREFERENCE_KEY); - // Put the shortcutPreference before radioButtonPreference. mShortcutPreference.setPersistent(false); mShortcutPreference.setKey(getShortcutPreferenceKey()); mShortcutPreference.setTitle(R.string.accessibility_shortcut_title); - mShortcutPreference.setOnClickListener(this); mShortcutPreference.setSummary(getShortcutTypeSummary(getPrefContext())); + mShortcutPreference.setOnClickListener(this); + // Put the shortcutPreference before previewPreference. mShortcutPreference.setOrder(previewPreference.getOrder() - 1); - preferenceScreen.addPreference(mShortcutPreference); // TODO(b/142530063): Check the new key to decide whether checkbox should be checked. + preferenceScreen.addPreference(mShortcutPreference); } - public String getShortcutPreferenceKey() { + private void updateShortcutPreference() { + final PreferenceScreen preferenceScreen = getPreferenceScreen(); + final ShortcutPreference shortcutPreference = preferenceScreen.findPreference( + getShortcutPreferenceKey()); + + if (shortcutPreference != null) { + // TODO(b/142531156): Replace PreferredShortcutType.SOFTWARE value with dialog shortcut + // preferred key. + shortcutPreference.setChecked( + AccessibilityUtil.hasValueInSettings(getContext(), + PreferredShortcutType.SOFTWARE, + getComponentName())); + } + } + + private String getShortcutPreferenceKey() { return KEY_SHORTCUT_PREFERENCE; } + private ComponentName getComponentName() { + return COLOR_INVERSION_COMPONENT_NAME; + } + @Override public void onCheckboxClicked(ShortcutPreference preference) { if (preference.getChecked()) { - // TODO(b/142530063): Enable shortcut when checkbox is checked. + // TODO(b/142531156): Replace PreferredShortcutType.SOFTWARE value with dialog shortcut + // preferred key. + AccessibilityUtil.optInValueToSettings(getContext(), PreferredShortcutType.SOFTWARE, + getComponentName()); } else { - // TODO(b/142530063): Disable shortcut when checkbox is unchecked. + // TODO(b/142531156): Replace PreferredShortcutType.SOFTWARE value with dialog shortcut + // preferred key. + AccessibilityUtil.optOutValueFromSettings(getContext(), PreferredShortcutType.SOFTWARE, + getComponentName()); } } @Override public void onSettingsClicked(ShortcutPreference preference) { - mShortcutType = getShortcutType(getPrefContext()); + mPreferredShortcutType = getPreferredShortcutType(getPrefContext()); showDialog(DIALOG_ID_EDIT_SHORTCUT); } diff --git a/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java index 7fb05da7fb0..7a77b9197aa 100644 --- a/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java @@ -16,8 +16,11 @@ package com.android.settings.accessibility; +import static com.android.internal.accessibility.AccessibilityShortcutController.DALTONIZER_COMPONENT_NAME; + import android.app.Dialog; import android.app.settings.SettingsEnums; +import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; import android.content.res.Resources; @@ -35,7 +38,7 @@ import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import com.android.settings.R; -import com.android.settings.accessibility.AccessibilityUtil.ShortcutType; +import com.android.settings.accessibility.AccessibilityUtil.PreferredShortcutType; import com.android.settings.accessibility.AccessibilityUtil.State; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.widget.SwitchBar; @@ -57,10 +60,11 @@ public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePrefe 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 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 mShortcutType = ShortcutType.DEFAULT; + private int mPreferredShortcutType = PreferredShortcutType.DEFAULT; private CheckBox mSoftwareTypeCheckBox; private CheckBox mHardwareTypeCheckBox; @@ -95,7 +99,7 @@ public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePrefe @Override public void onSaveInstanceState(Bundle outState) { - outState.putInt(EXTRA_SHORTCUT_TYPE, mShortcutType); + outState.putInt(EXTRA_SHORTCUT_TYPE, mPreferredShortcutType); super.onSaveInstanceState(outState); } @@ -108,6 +112,7 @@ public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePrefe ((DaltonizerRadioButtonPreferenceController) controller).displayPreference( getPreferenceScreen()); } + updateShortcutPreference(); } @Override @@ -143,8 +148,8 @@ public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePrefe } private void updateAlertDialogCheckState() { - updateCheckStatus(mSoftwareTypeCheckBox, ShortcutType.SOFTWARE); - updateCheckStatus(mHardwareTypeCheckBox, ShortcutType.HARDWARE); + updateCheckStatus(mSoftwareTypeCheckBox, PreferredShortcutType.SOFTWARE); + updateCheckStatus(mHardwareTypeCheckBox, PreferredShortcutType.HARDWARE); } private void updateAlertDialogEnableState() { @@ -158,48 +163,48 @@ public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePrefe } } - private void updateCheckStatus(CheckBox checkBox, @ShortcutType int type) { - checkBox.setChecked((mShortcutType & type) == type); + private void updateCheckStatus(CheckBox checkBox, @PreferredShortcutType int type) { + checkBox.setChecked((mPreferredShortcutType & type) == type); checkBox.setOnClickListener(v -> { - updateShortcutType(false); + updatePreferredShortcutType(false); updateAlertDialogEnableState(); }); } - private void updateShortcutType(boolean saveToDB) { - mShortcutType = ShortcutType.DEFAULT; + private void updatePreferredShortcutType(boolean saveToDB) { + mPreferredShortcutType = PreferredShortcutType.DEFAULT; if (mSoftwareTypeCheckBox.isChecked()) { - mShortcutType |= ShortcutType.SOFTWARE; + mPreferredShortcutType |= PreferredShortcutType.SOFTWARE; } if (mHardwareTypeCheckBox.isChecked()) { - mShortcutType |= ShortcutType.HARDWARE; + mPreferredShortcutType |= PreferredShortcutType.HARDWARE; } if (saveToDB) { - setShortcutType(mShortcutType); + setPreferredShortcutType(mPreferredShortcutType); } } - private void setSecureIntValue(String key, @ShortcutType int value) { + private void setSecureIntValue(String key, @PreferredShortcutType int value) { Settings.Secure.putIntForUser(getPrefContext().getContentResolver(), key, value, getPrefContext().getContentResolver().getUserId()); } - private void setShortcutType(@ShortcutType int type) { + private void setPreferredShortcutType(@PreferredShortcutType int type) { setSecureIntValue(KEY_SHORTCUT_TYPE, type); } private String getShortcutTypeSummary(Context context) { - final int shortcutType = getShortcutType(context); + final int shortcutType = getPreferredShortcutType(context); 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 & ShortcutType.SOFTWARE) == ShortcutType.SOFTWARE) { + if ((shortcutType & PreferredShortcutType.SOFTWARE) == PreferredShortcutType.SOFTWARE) { list.add(softwareTitle); } - if ((shortcutType & ShortcutType.HARDWARE) == ShortcutType.HARDWARE) { + if ((shortcutType & PreferredShortcutType.HARDWARE) == PreferredShortcutType.HARDWARE) { final CharSequence hardwareTitle = context.getText( R.string.accessibility_shortcut_edit_dialog_title_hardware); list.add(hardwareTitle); @@ -213,20 +218,21 @@ public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePrefe return AccessibilityUtil.capitalize(joinStrings); } - @ShortcutType - private int getShortcutType(Context context) { - return getSecureIntValue(context, KEY_SHORTCUT_TYPE, ShortcutType.SOFTWARE); + @PreferredShortcutType + private int getPreferredShortcutType(Context context) { + return getSecureIntValue(context, KEY_SHORTCUT_TYPE, PreferredShortcutType.SOFTWARE); } - @ShortcutType - private int getSecureIntValue(Context context, String key, @ShortcutType int defaultValue) { + @PreferredShortcutType + private int getSecureIntValue(Context context, String key, + @PreferredShortcutType int defaultValue) { return Settings.Secure.getIntForUser( context.getContentResolver(), key, defaultValue, context.getContentResolver().getUserId()); } private void callOnAlertDialogCheckboxClicked(DialogInterface dialog, int which) { - updateShortcutType(true); + updatePreferredShortcutType(true); mShortcutPreference.setSummary( getShortcutTypeSummary(getPrefContext())); } @@ -288,39 +294,72 @@ public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePrefe @Override public void onCheckboxClicked(ShortcutPreference preference) { if (preference.getChecked()) { - // TODO(b/142530063): Enable shortcut when checkbox is checked. + // TODO(b/142531156): Replace PreferredShortcutType.SOFTWARE value with dialog shortcut + // preferred key. + AccessibilityUtil.optInValueToSettings(getContext(), PreferredShortcutType.SOFTWARE, + getComponentName()); } else { - // TODO(b/142530063): Disable shortcut when checkbox is unchecked. + // TODO(b/142531156): Replace PreferredShortcutType.SOFTWARE value with dialog shortcut + // preferred key. + AccessibilityUtil.optOutValueFromSettings(getContext(), PreferredShortcutType.SOFTWARE, + getComponentName()); } } @Override public void onSettingsClicked(ShortcutPreference preference) { - mShortcutType = getShortcutType(getPrefContext()); + mPreferredShortcutType = getPreferredShortcutType(getPrefContext()); showDialog(DIALOG_ID_EDIT_SHORTCUT); } private void initShortcutPreference(Bundle savedInstanceState) { - // Restore the Shortcut type + // Restore the PreferredShortcut type if (savedInstanceState != null) { - mShortcutType = savedInstanceState.getInt(EXTRA_SHORTCUT_TYPE, ShortcutType.DEFAULT); + mPreferredShortcutType = savedInstanceState.getInt(EXTRA_SHORTCUT_TYPE, + PreferredShortcutType.DEFAULT); } - if (mShortcutType == ShortcutType.DEFAULT) { - mShortcutType = getShortcutType(getPrefContext()); + if (mPreferredShortcutType == PreferredShortcutType.DEFAULT) { + mPreferredShortcutType = getPreferredShortcutType(getPrefContext()); } // Initial ShortcutPreference widget final PreferenceScreen preferenceScreen = getPreferenceScreen(); mShortcutPreference = new ShortcutPreference( preferenceScreen.getContext(), null); + mShortcutPreference.setPersistent(false); + mShortcutPreference.setKey(getShortcutPreferenceKey()); mShortcutPreference.setTitle(R.string.accessibility_shortcut_title); - mShortcutPreference.setOnClickListener(this); mShortcutPreference.setSummary(getShortcutTypeSummary(getPrefContext())); - // Put the shortcutPreference before radioButtonPreference. + mShortcutPreference.setOnClickListener(this); final RadioButtonPreference radioButtonPreference = findPreference(PREFERENCE_KEY); + // Put the shortcutPreference before radioButtonPreference. mShortcutPreference.setOrder(radioButtonPreference.getOrder() - 1); - preferenceScreen.addPreference(mShortcutPreference); // TODO(b/142530063): Check the new key to decide whether checkbox should be checked. + preferenceScreen.addPreference(mShortcutPreference); + } + + private void updateShortcutPreference() { + final PreferenceScreen preferenceScreen = getPreferenceScreen(); + final ShortcutPreference shortcutPreference = preferenceScreen.findPreference( + getShortcutPreferenceKey()); + + if (shortcutPreference != null) { + // TODO(b/142531156): Replace PreferredShortcutType.SOFTWARE value with dialog shortcut + // preferred key. + shortcutPreference.setChecked( + AccessibilityUtil.hasValueInSettings(getContext(), + PreferredShortcutType.SOFTWARE, + getComponentName())); + } + + } + + private String getShortcutPreferenceKey() { + return KEY_SHORTCUT_PREFERENCE; + } + + private ComponentName getComponentName() { + return DALTONIZER_COMPONENT_NAME; } public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = diff --git a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java index 515d80c35c1..86936906633 100644 --- a/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleScreenMagnificationPreferenceFragment.java @@ -16,6 +16,8 @@ package com.android.settings.accessibility; +import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME; + import android.app.Dialog; import android.app.settings.SettingsEnums; import android.content.ContentResolver; @@ -45,13 +47,14 @@ import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceViewHolder; import com.android.settings.R; -import com.android.settings.accessibility.AccessibilityUtil.ShortcutType; +import com.android.settings.accessibility.AccessibilityUtil.PreferredShortcutType; import com.android.settings.widget.SwitchBar; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.List; +import java.util.StringJoiner; public class ToggleScreenMagnificationPreferenceFragment extends ToggleFeaturePreferenceFragment implements SwitchBar.OnSwitchChangeListener, @@ -62,10 +65,18 @@ public class ToggleScreenMagnificationPreferenceFragment extends // 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 ShortcutPreference mShortcutPreference; - private int mShortcutType = ShortcutType.DEFAULT; + private int mPreferredShortcutType = PreferredShortcutType.DEFAULT; private CheckBox mSoftwareTypeCheckBox; private CheckBox mHardwareTypeCheckBox; private CheckBox mTripleTapTypeCheckBox; + private static final String KEY_SHORTCUT_PREFERENCE = "shortcut_preference"; + + // TODO(b/147021230): Will move common functions and variables to + // android/internal/accessibility folder. For now, magnification need to be treated + // individually. + private static final char COMPONENT_NAME_SEPARATOR = ':'; + private static final TextUtils.SimpleStringSplitter sStringColonSplitter = + new TextUtils.SimpleStringSplitter(COMPONENT_NAME_SEPARATOR); protected class VideoPreference extends Preference { private ImageView mVideoBackgroundView; @@ -187,7 +198,7 @@ public class ToggleScreenMagnificationPreferenceFragment extends @Override public void onSaveInstanceState(Bundle outState) { - outState.putInt(EXTRA_SHORTCUT_TYPE, mShortcutType); + outState.putInt(EXTRA_SHORTCUT_TYPE, mPreferredShortcutType); super.onSaveInstanceState(outState); } @@ -201,6 +212,7 @@ public class ToggleScreenMagnificationPreferenceFragment extends } updateConfigurationWarningIfNeeded(); + updateShortcutPreference(); } @Override @@ -243,9 +255,9 @@ public class ToggleScreenMagnificationPreferenceFragment extends } private void updateAlertDialogCheckState() { - updateCheckStatus(mSoftwareTypeCheckBox, ShortcutType.SOFTWARE); - updateCheckStatus(mHardwareTypeCheckBox, ShortcutType.HARDWARE); - updateCheckStatus(mTripleTapTypeCheckBox, ShortcutType.TRIPLETAP); + updateCheckStatus(mSoftwareTypeCheckBox, PreferredShortcutType.SOFTWARE); + updateCheckStatus(mHardwareTypeCheckBox, PreferredShortcutType.HARDWARE); + updateCheckStatus(mTripleTapTypeCheckBox, PreferredShortcutType.TRIPLETAP); } private void updateAlertDialogEnableState() { @@ -262,57 +274,57 @@ public class ToggleScreenMagnificationPreferenceFragment extends } } - private void updateCheckStatus(CheckBox checkBox, @ShortcutType int type) { - checkBox.setChecked((mShortcutType & type) == type); + private void updateCheckStatus(CheckBox checkBox, @PreferredShortcutType int type) { + checkBox.setChecked((mPreferredShortcutType & type) == type); checkBox.setOnClickListener(v -> { - updateShortcutType(false); + updatePreferredShortcutType(false); updateAlertDialogEnableState(); }); } - private void updateShortcutType(boolean saveToDB) { - mShortcutType = ShortcutType.DEFAULT; + private void updatePreferredShortcutType(boolean saveToDB) { + mPreferredShortcutType = PreferredShortcutType.DEFAULT; if (mSoftwareTypeCheckBox.isChecked()) { - mShortcutType |= ShortcutType.SOFTWARE; + mPreferredShortcutType |= PreferredShortcutType.SOFTWARE; } if (mHardwareTypeCheckBox.isChecked()) { - mShortcutType |= ShortcutType.HARDWARE; + mPreferredShortcutType |= PreferredShortcutType.HARDWARE; } if (mTripleTapTypeCheckBox.isChecked()) { - mShortcutType |= ShortcutType.TRIPLETAP; + mPreferredShortcutType |= PreferredShortcutType.TRIPLETAP; } if (saveToDB) { - setShortcutType(mShortcutType); + setPreferredShortcutType(mPreferredShortcutType); } } - private void setSecureIntValue(String key, @ShortcutType int value) { + private void setSecureIntValue(String key, @PreferredShortcutType int value) { Settings.Secure.putIntForUser(getPrefContext().getContentResolver(), key, value, getPrefContext().getContentResolver().getUserId()); } - private void setShortcutType(@ShortcutType int type) { + private void setPreferredShortcutType(@PreferredShortcutType int type) { setSecureIntValue(KEY_SHORTCUT_TYPE, type); } private String getShortcutTypeSummary(Context context) { - final int shortcutType = getShortcutType(context); + final int shortcutType = getPreferredShortcutType(context); 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 & ShortcutType.SOFTWARE) == ShortcutType.SOFTWARE) { + if ((shortcutType & PreferredShortcutType.SOFTWARE) == PreferredShortcutType.SOFTWARE) { list.add(softwareTitle); } - if ((shortcutType & ShortcutType.HARDWARE) == ShortcutType.HARDWARE) { + if ((shortcutType & PreferredShortcutType.HARDWARE) == PreferredShortcutType.HARDWARE) { final CharSequence hardwareTitle = context.getText( R.string.accessibility_shortcut_edit_dialog_title_hardware); list.add(hardwareTitle); } - if ((shortcutType & ShortcutType.TRIPLETAP) == ShortcutType.TRIPLETAP) { + if ((shortcutType & PreferredShortcutType.TRIPLETAP) == PreferredShortcutType.TRIPLETAP) { final CharSequence tripleTapTitle = context.getText( R.string.accessibility_shortcut_edit_dialog_title_triple_tap); list.add(tripleTapTitle); @@ -326,20 +338,21 @@ public class ToggleScreenMagnificationPreferenceFragment extends return AccessibilityUtil.capitalize(joinStrings); } - @ShortcutType - private int getShortcutType(Context context) { - return getSecureIntValue(context, KEY_SHORTCUT_TYPE, ShortcutType.SOFTWARE); + @PreferredShortcutType + private int getPreferredShortcutType(Context context) { + return getSecureIntValue(context, KEY_SHORTCUT_TYPE, PreferredShortcutType.SOFTWARE); } - @ShortcutType - private int getSecureIntValue(Context context, String key, @ShortcutType int defaultValue) { + @PreferredShortcutType + private int getSecureIntValue(Context context, String key, + @PreferredShortcutType int defaultValue) { return Settings.Secure.getIntForUser( context.getContentResolver(), key, defaultValue, context.getContentResolver().getUserId()); } private void callOnAlertDialogCheckboxClicked(DialogInterface dialog, int which) { - updateShortcutType(true); + updatePreferredShortcutType(true); mShortcutPreference.setSummary( getShortcutTypeSummary(getPrefContext())); } @@ -428,38 +441,67 @@ public class ToggleScreenMagnificationPreferenceFragment extends @Override public void onCheckboxClicked(ShortcutPreference preference) { if (preference.getChecked()) { - // TODO(b/142530063): Enable shortcut when checkbox is checked. + // TODO(b/142531156): Replace PreferredShortcutType.SOFTWARE value with dialog shortcut + // preferred key. + // TODO(b/142531156): ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED need to be treated + // as special case in this file. + optInMagnificationValueToSettings(getContext(), PreferredShortcutType.SOFTWARE); } else { - // TODO(b/142530063): Disable shortcut when checkbox is unchecked. + // TODO(b/142531156): Replace PreferredShortcutType.SOFTWARE value with dialog shortcut + // preferred key. + // TODO(b/142531156): ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED need to be treated + // as special case in this file. + optOutMagnificationValueFromSettings(getContext(), PreferredShortcutType.SOFTWARE); } } @Override public void onSettingsClicked(ShortcutPreference preference) { - mShortcutType = getShortcutType(getPrefContext()); + mPreferredShortcutType = getPreferredShortcutType(getPrefContext()); showDialog(DialogType.EDIT_SHORTCUT); } private void initShortcutPreference(Bundle savedInstanceState) { - // Restore the Shortcut type + // Restore the PreferredShortcut type if (savedInstanceState != null) { - mShortcutType = savedInstanceState.getInt(EXTRA_SHORTCUT_TYPE, ShortcutType.DEFAULT); + mPreferredShortcutType = savedInstanceState.getInt(EXTRA_SHORTCUT_TYPE, + PreferredShortcutType.DEFAULT); } - if (mShortcutType == ShortcutType.DEFAULT) { - mShortcutType = getShortcutType(getPrefContext()); + if (mPreferredShortcutType == PreferredShortcutType.DEFAULT) { + mPreferredShortcutType = getPreferredShortcutType(getPrefContext()); } // Initial ShortcutPreference widget final PreferenceScreen preferenceScreen = getPreferenceScreen(); mShortcutPreference = new ShortcutPreference( preferenceScreen.getContext(), null); + mShortcutPreference.setPersistent(false); + mShortcutPreference.setKey(getShortcutPreferenceKey()); mShortcutPreference.setTitle(R.string.accessibility_magnification_shortcut_title); - mShortcutPreference.setOnClickListener(this); mShortcutPreference.setSummary(getShortcutTypeSummary(getPrefContext())); + mShortcutPreference.setOnClickListener(this); // Put the shortcutPreference before videoPreference. mShortcutPreference.setOrder(mVideoPreference.getOrder() - 1); + // TODO(b/142530063): Check the new setting key to decide which summary should be shown. preferenceScreen.addPreference(mShortcutPreference); - // TODO(b/142530063): Check the new key to decide whether checkbox should be checked. + } + + private void updateShortcutPreference() { + final PreferenceScreen preferenceScreen = getPreferenceScreen(); + final ShortcutPreference shortcutPreference = preferenceScreen.findPreference( + getShortcutPreferenceKey()); + + if (shortcutPreference != null) { + // TODO(b/142531156): Replace PreferredShortcutType.SOFTWARE value with dialog shortcut + // preferred key. + shortcutPreference.setChecked( + hasMagnificationValueInSettings(getContext(), + PreferredShortcutType.SOFTWARE)); + } + } + + private String getShortcutPreferenceKey() { + return KEY_SHORTCUT_PREFERENCE; } private void updateConfigurationWarningIfNeeded() { @@ -479,4 +521,68 @@ public class ToggleScreenMagnificationPreferenceFragment extends int EDIT_SHORTCUT = 3; } + private static void optInMagnificationValueToSettings(Context context, + @PreferredShortcutType int shortcutType) { + final String targetKey = AccessibilityUtil.convertKeyFromSettings(shortcutType); + final String targetString = Settings.Secure.getString(context.getContentResolver(), + targetKey); + + if (TextUtils.isEmpty(targetString)) { + return; + } + + if (hasMagnificationValueInSettings(context, shortcutType)) { + return; + } + + final StringJoiner joiner = new StringJoiner(String.valueOf(COMPONENT_NAME_SEPARATOR)); + + joiner.add(Settings.Secure.getString(context.getContentResolver(), targetKey)); + joiner.add(MAGNIFICATION_CONTROLLER_NAME); + + Settings.Secure.putString(context.getContentResolver(), targetKey, joiner.toString()); + } + + private static void optOutMagnificationValueFromSettings(Context context, + @PreferredShortcutType 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(), + targetKey); + + if (TextUtils.isEmpty(targetString)) { + return; + } + + sStringColonSplitter.setString(targetString); + while (sStringColonSplitter.hasNext()) { + final String name = sStringColonSplitter.next(); + if (TextUtils.isEmpty(name) || MAGNIFICATION_CONTROLLER_NAME.equals(name)) { + continue; + } + joiner.add(name); + } + + Settings.Secure.putString(context.getContentResolver(), targetKey, joiner.toString()); + } + + private static boolean hasMagnificationValueInSettings(Context context, + @PreferredShortcutType int shortcutType) { + final String targetKey = AccessibilityUtil.convertKeyFromSettings(shortcutType); + final String targetString = Settings.Secure.getString(context.getContentResolver(), + targetKey); + + if (TextUtils.isEmpty(targetString)) { + return false; + } + + sStringColonSplitter.setString(targetString); + while (sStringColonSplitter.hasNext()) { + final String name = sStringColonSplitter.next(); + if (MAGNIFICATION_CONTROLLER_NAME.equals(name)) { + return true; + } + } + return false; + } } diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityUtilTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityUtilTest.java index 2ccfd056e5f..89ad8120d90 100644 --- a/tests/robotests/src/com/android/settings/accessibility/AccessibilityUtilTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityUtilTest.java @@ -28,6 +28,7 @@ import android.os.Build; import android.provider.Settings; import com.android.settings.R; +import com.android.settings.accessibility.AccessibilityUtil.PreferredShortcutType; import org.junit.Before; import org.junit.Test; @@ -45,7 +46,14 @@ public final class AccessibilityUtilTest { private static final String SECURE_TEST_KEY = "secure_test_key"; private static final String DUMMY_PACKAGE_NAME = "com.dummy.example"; private static final String DUMMY_CLASS_NAME = DUMMY_PACKAGE_NAME + ".dummy_a11y_service"; - private static final String DUMMY_COMPONENT_NAME = DUMMY_PACKAGE_NAME + "/" + DUMMY_CLASS_NAME; + private static final String DUMMY_CLASS_NAME2 = DUMMY_PACKAGE_NAME + ".dummy_a11y_service2"; + private static final ComponentName DUMMY_COMPONENT_NAME = new ComponentName(DUMMY_PACKAGE_NAME, + DUMMY_CLASS_NAME); + private static final ComponentName DUMMY_COMPONENT_NAME2 = new ComponentName(DUMMY_PACKAGE_NAME, + DUMMY_CLASS_NAME2); + private static final String SOFTWARE_SHORTCUT_KEY = + Settings.Secure.ACCESSIBILITY_BUTTON_TARGET_COMPONENT; + private Context mContext; @Before @@ -124,6 +132,57 @@ public final class AccessibilityUtilTest { AccessibilityUtil.AccessibilityServiceFragmentType.INTUITIVE); } + @Test + public void hasValueInSettings_dummyComponentName_hasValue() { + putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, DUMMY_COMPONENT_NAME.flattenToString()); + + assertThat(AccessibilityUtil.hasValueInSettings(mContext, PreferredShortcutType.SOFTWARE, + DUMMY_COMPONENT_NAME)).isTrue(); + } + + @Test + public void optInValueToSettings_optInDummyComponentName2_haveDummyComponentName2String() { + putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, DUMMY_COMPONENT_NAME.flattenToString()); + AccessibilityUtil.optInValueToSettings(mContext, PreferredShortcutType.SOFTWARE, + DUMMY_COMPONENT_NAME2); + + assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEqualTo( + DUMMY_COMPONENT_NAME.flattenToString() + ":" + + DUMMY_COMPONENT_NAME2.flattenToString()); + } + + @Test + public void optInValueToSettings_optInTwoDummyComponentName_haveOneDummyComponentName2String() { + putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, DUMMY_COMPONENT_NAME.flattenToString()); + AccessibilityUtil.optInValueToSettings(mContext, PreferredShortcutType.SOFTWARE, + DUMMY_COMPONENT_NAME2); + AccessibilityUtil.optInValueToSettings(mContext, PreferredShortcutType.SOFTWARE, + DUMMY_COMPONENT_NAME2); + + assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEqualTo( + DUMMY_COMPONENT_NAME.flattenToString() + ":" + + DUMMY_COMPONENT_NAME2.flattenToString()); + } + + @Test + public void optOutValueFromSettings_optOutDummyComponentName_emptyValue() { + putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, DUMMY_COMPONENT_NAME.flattenToString()); + AccessibilityUtil.optOutValueFromSettings(mContext, PreferredShortcutType.SOFTWARE, + DUMMY_COMPONENT_NAME); + + assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEmpty(); + } + + @Test + public void optOutValueFromSettings_optOutDummyComponentName2_haveDummyComponentName() { + putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, DUMMY_COMPONENT_NAME.flattenToString() + ":" + + DUMMY_COMPONENT_NAME2.flattenToString()); + AccessibilityUtil.optOutValueFromSettings(mContext, PreferredShortcutType.SOFTWARE, + DUMMY_COMPONENT_NAME2); + + assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEqualTo( + DUMMY_COMPONENT_NAME.flattenToString()); + } private AccessibilityServiceInfo getMockAccessibilityServiceInfo() { final ApplicationInfo applicationInfo = new ApplicationInfo(); @@ -139,9 +198,7 @@ public final class AccessibilityUtilTest { try { final AccessibilityServiceInfo info = new AccessibilityServiceInfo(resolveInfo, mContext); - final ComponentName componentName = ComponentName.unflattenFromString( - DUMMY_COMPONENT_NAME); - info.setComponentName(componentName); + info.setComponentName(DUMMY_COMPONENT_NAME); return info; } catch (XmlPullParserException | IOException e) { // Do nothing @@ -149,4 +206,12 @@ public final class AccessibilityUtilTest { return null; } + + private void putStringIntoSettings(String key, String componentName) { + Settings.Secure.putString(mContext.getContentResolver(), key, componentName); + } + + private String getStringFromSettings(String key) { + return Settings.Secure.getString(mContext.getContentResolver(), key); + } }