Accessibility shortcut secondary action - save and restore shortcut key

- Implement onCheckboxClicked() to save shortcut key
- restore shortcut key when onViewCreated()
- Use preferredShortcutType to handle settings key

Bug: 142530063
Test: make -j52 RunSettingsRoboTests ROBOTEST_FILTER=AccessibilityUtilTest
Change-Id: Iabe636641968d346e52becea19b6e201ea5bc1fb
diff --git a/src/com/android/settings/accessibility/AccessibilityUtil.java b/src/com/android/settings/accessibility/AccessibilityUtil.java
index 4b3a341..371afa1 100644
--- a/src/com/android/settings/accessibility/AccessibilityUtil.java
+++ b/src/com/android/settings/accessibility/AccessibilityUtil.java
@@ -19,16 +19,20 @@
 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 @@
         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 @@
      */
     @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 @@
     }
 
     /**
-     * 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 @@
                 ? 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 269bc04..e53154a 100644
--- a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java
@@ -47,7 +47,7 @@
 
 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 @@
         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 @@
 
     @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 @@
     }
 
     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 @@
         }
     }
 
-    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<CharSequence> 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 @@
         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 @@
     }
 
     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 @@
                 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 @@
     @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 1c7a5f3..c32248d 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.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 @@
     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,11 +142,17 @@
 
     @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) {
             final CharSequence dialogTitle = getActivity().getString(
@@ -167,8 +176,8 @@
     }
 
     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 @@
         }
     }
 
-    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<CharSequence> 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 @@
         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 @@
     }
 
     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 @@
         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 7fb05da..7a77b91 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.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 @@
     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<AbstractPreferenceController> 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 @@
 
     @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 @@
             ((DaltonizerRadioButtonPreferenceController) controller).displayPreference(
                     getPreferenceScreen());
         }
+        updateShortcutPreference();
     }
 
     @Override
@@ -143,8 +148,8 @@
     }
 
     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 @@
         }
     }
 
-    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<CharSequence> 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 @@
         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 @@
     @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 515d80c..8693690 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.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 @@
     // 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 @@
 
     @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 @@
         }
 
         updateConfigurationWarningIfNeeded();
+        updateShortcutPreference();
     }
 
     @Override
@@ -243,9 +255,9 @@
     }
 
     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 @@
         }
     }
 
-    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<CharSequence> 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 @@
         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 @@
     @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 @@
         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 2ccfd05..89ad812 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.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 @@
     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 @@
                 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 @@
         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 @@
 
         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);
+    }
 }