diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index eb2b869..ac90662 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -1014,6 +1014,13 @@
         <item>\?</item>
     </string-array>
 
+    <!-- Summary for color space adjustment modes for accessibility -->
+    <string-array name="daltonizer_mode_summary" translatable="false">
+        <item>@string/daltonizer_mode_deuteranomaly</item>
+        <item>@string/daltonizer_mode_protanomaly</item>
+        <item>@string/daltonizer_mode_tritanomaly</item>
+    </string-array>
+
     <!-- Keys for color space adjustment modes for accessibility -->
     <string-array name="daltonizer_mode_keys" translatable="false">
         <item>daltonizer_mode_deuteranomaly</item>
diff --git a/src/com/android/settings/accessibility/DaltonizerPreferenceController.java b/src/com/android/settings/accessibility/DaltonizerPreferenceController.java
index efdfaed..e026313 100644
--- a/src/com/android/settings/accessibility/DaltonizerPreferenceController.java
+++ b/src/com/android/settings/accessibility/DaltonizerPreferenceController.java
@@ -16,91 +16,23 @@
 
 package com.android.settings.accessibility;
 
-import android.content.ContentResolver;
 import android.content.Context;
-import android.content.res.Resources;
 import android.provider.Settings;
-import android.view.accessibility.AccessibilityManager;
-
-import androidx.lifecycle.LifecycleObserver;
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
 
 import com.android.settings.R;
 import com.android.settings.core.BasePreferenceController;
-import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.widget.RadioButtonPreference;
 
 import com.google.common.primitives.Ints;
 
-import java.util.HashMap;
-import java.util.Map;
+/** Controller that shows and updates the color correction summary. */
+public class DaltonizerPreferenceController extends BasePreferenceController {
 
-/** Controller class that control accessibility daltonizer settings. */
-public class DaltonizerPreferenceController extends BasePreferenceController implements
-        LifecycleObserver, RadioButtonPreference.OnClickListener {
-    private static final String TYPE = Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER;
+    private static final String DALTONIZER_TYPE = Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER;
+    private static final String DALTONIZER_ENABLED =
+            Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED;
 
-    // pair the preference key and daltonizer value.
-    private final Map<String, Integer> mAccessibilityDaltonizerKeyToValueMap = new HashMap<>();
-
-    // RadioButtonPreference key, each preference represent a daltonizer value.
-    private final ContentResolver mContentResolver;
-    private final Resources mResources;
-    private DaltonizerPreferenceController.OnChangeListener mOnChangeListener;
-    private RadioButtonPreference mPreference;
-    private int mAccessibilityDaltonizerValue;
-
-    public DaltonizerPreferenceController(Context context, Lifecycle lifecycle,
-            String preferenceKey) {
+    public DaltonizerPreferenceController(Context context, String preferenceKey) {
         super(context, preferenceKey);
-
-        mContentResolver = context.getContentResolver();
-        mResources = context.getResources();
-
-        if (lifecycle != null) {
-            lifecycle.addObserver(this);
-        }
-    }
-
-    protected static int getSecureAccessibilityDaltonizerValue(ContentResolver resolver,
-            String name) {
-        final String daltonizerStringValue = Settings.Secure.getString(resolver, name);
-        if (daltonizerStringValue == null) {
-            return AccessibilityManager.DALTONIZER_CORRECT_DEUTERANOMALY;
-        }
-        final Integer daltonizerIntValue = Ints.tryParse(daltonizerStringValue);
-        return daltonizerIntValue == null ? AccessibilityManager.DALTONIZER_CORRECT_DEUTERANOMALY
-                : daltonizerIntValue;
-    }
-
-    public void setOnChangeListener(DaltonizerPreferenceController.OnChangeListener listener) {
-        mOnChangeListener = listener;
-    }
-
-    private Map<String, Integer> getDaltonizerValueToKeyMap() {
-        if (mAccessibilityDaltonizerKeyToValueMap.size() == 0) {
-
-            final String[] daltonizerKeys = mResources.getStringArray(
-                    R.array.daltonizer_mode_keys);
-
-            final int[] daltonizerValues = mResources.getIntArray(
-                    R.array.daltonizer_type_values);
-
-            final int daltonizerValueCount = daltonizerValues.length;
-            for (int i = 0; i < daltonizerValueCount; i++) {
-                mAccessibilityDaltonizerKeyToValueMap.put(daltonizerKeys[i], daltonizerValues[i]);
-            }
-        }
-        return mAccessibilityDaltonizerKeyToValueMap;
-    }
-
-    private void putSecureString(String name, String value) {
-        Settings.Secure.putString(mContentResolver, name, value);
-    }
-
-    private void handlePreferenceChange(String value) {
-        putSecureString(TYPE, value);
     }
 
     @Override
@@ -109,50 +41,22 @@
     }
 
     @Override
-    public void displayPreference(PreferenceScreen screen) {
-        super.displayPreference(screen);
-        mPreference = (RadioButtonPreference)
-                screen.findPreference(getPreferenceKey());
-        mPreference.setOnClickListener(this);
-        updateState(mPreference);
+    public CharSequence getSummary() {
+        final String[] daltonizerSummarys = mContext.getResources().getStringArray(
+                R.array.daltonizer_mode_summary);
+        final int[] daltonizerValues = mContext.getResources().getIntArray(
+                R.array.daltonizer_type_values);
+        final int timeoutValue =
+                DaltonizerRadioButtonPreferenceController.getSecureAccessibilityDaltonizerValue(
+                        mContext.getContentResolver(), DALTONIZER_TYPE);
+        final int idx = Ints.indexOf(daltonizerValues, timeoutValue);
+        final String serviceSummary = daltonizerSummarys[idx == -1 ? 0 : idx];
+
+        final CharSequence serviceState = AccessibilityUtil.getSummary(mContext,
+                DALTONIZER_ENABLED);
+
+        return mContext.getString(
+                R.string.preference_summary_default_combination,
+                serviceState, serviceSummary);
     }
-
-    @Override
-    public void onRadioButtonClicked(RadioButtonPreference preference) {
-        final int value = getDaltonizerValueToKeyMap().get(mPreferenceKey);
-        handlePreferenceChange(String.valueOf(value));
-        if (mOnChangeListener != null) {
-            mOnChangeListener.onCheckedChanged(mPreference);
-        }
-    }
-
-    private int getAccessibilityDaltonizerValue() {
-        final int daltonizerValue = getSecureAccessibilityDaltonizerValue(mContentResolver,
-                TYPE);
-        return daltonizerValue;
-    }
-
-    protected void updatePreferenceCheckedState(int value) {
-        if (mAccessibilityDaltonizerValue == value) {
-            mPreference.setChecked(true);
-        }
-    }
-
-    @Override
-    public void updateState(Preference preference) {
-        super.updateState(preference);
-        mAccessibilityDaltonizerValue = getAccessibilityDaltonizerValue();
-
-        // reset RadioButton
-        mPreference.setChecked(false);
-        final int preferenceValue = getDaltonizerValueToKeyMap().get(mPreference.getKey());
-        updatePreferenceCheckedState(preferenceValue);
-    }
-
-    /** Listener interface handles checked event. */
-    public interface OnChangeListener {
-        /** A hook that is called when preference checked.*/
-        void onCheckedChanged(Preference preference);
-    }
-
-}
\ No newline at end of file
+}
diff --git a/src/com/android/settings/accessibility/DaltonizerRadioButtonPreferenceController.java b/src/com/android/settings/accessibility/DaltonizerRadioButtonPreferenceController.java
new file mode 100644
index 0000000..dd5eb10
--- /dev/null
+++ b/src/com/android/settings/accessibility/DaltonizerRadioButtonPreferenceController.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accessibility;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.res.Resources;
+import android.provider.Settings;
+import android.view.accessibility.AccessibilityManager;
+
+import androidx.lifecycle.LifecycleObserver;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
+
+import com.google.common.primitives.Ints;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/** Controller class that control radio button of accessibility daltonizer settings. */
+public class DaltonizerRadioButtonPreferenceController extends BasePreferenceController implements
+        LifecycleObserver, RadioButtonPreference.OnClickListener {
+    private static final String TYPE = Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER;
+
+    // pair the preference key and daltonizer value.
+    private final Map<String, Integer> mAccessibilityDaltonizerKeyToValueMap = new HashMap<>();
+
+    // RadioButtonPreference key, each preference represent a daltonizer value.
+    private final ContentResolver mContentResolver;
+    private final Resources mResources;
+    private DaltonizerRadioButtonPreferenceController.OnChangeListener mOnChangeListener;
+    private RadioButtonPreference mPreference;
+    private int mAccessibilityDaltonizerValue;
+
+    public DaltonizerRadioButtonPreferenceController(Context context, String preferenceKey) {
+        super(context, preferenceKey);
+
+        mContentResolver = context.getContentResolver();
+        mResources = context.getResources();
+    }
+
+    public DaltonizerRadioButtonPreferenceController(Context context, Lifecycle lifecycle,
+            String preferenceKey) {
+        super(context, preferenceKey);
+
+        mContentResolver = context.getContentResolver();
+        mResources = context.getResources();
+
+        if (lifecycle != null) {
+            lifecycle.addObserver(this);
+        }
+    }
+
+    protected static int getSecureAccessibilityDaltonizerValue(ContentResolver resolver,
+            String name) {
+        final String daltonizerStringValue = Settings.Secure.getString(resolver, name);
+        if (daltonizerStringValue == null) {
+            return AccessibilityManager.DALTONIZER_CORRECT_DEUTERANOMALY;
+        }
+        final Integer daltonizerIntValue = Ints.tryParse(daltonizerStringValue);
+        return daltonizerIntValue == null ? AccessibilityManager.DALTONIZER_CORRECT_DEUTERANOMALY
+                : daltonizerIntValue;
+    }
+
+    public void setOnChangeListener(
+            DaltonizerRadioButtonPreferenceController.OnChangeListener listener) {
+        mOnChangeListener = listener;
+    }
+
+    private Map<String, Integer> getDaltonizerValueToKeyMap() {
+        if (mAccessibilityDaltonizerKeyToValueMap.size() == 0) {
+
+            final String[] daltonizerKeys = mResources.getStringArray(
+                    R.array.daltonizer_mode_keys);
+
+            final int[] daltonizerValues = mResources.getIntArray(
+                    R.array.daltonizer_type_values);
+
+            final int daltonizerValueCount = daltonizerValues.length;
+            for (int i = 0; i < daltonizerValueCount; i++) {
+                mAccessibilityDaltonizerKeyToValueMap.put(daltonizerKeys[i], daltonizerValues[i]);
+            }
+        }
+        return mAccessibilityDaltonizerKeyToValueMap;
+    }
+
+    private void putSecureString(String name, String value) {
+        Settings.Secure.putString(mContentResolver, name, value);
+    }
+
+    private void handlePreferenceChange(String value) {
+        putSecureString(TYPE, value);
+    }
+
+    @Override
+    public int getAvailabilityStatus() {
+        return AVAILABLE;
+    }
+
+    @Override
+    public void displayPreference(PreferenceScreen screen) {
+        super.displayPreference(screen);
+        mPreference = (RadioButtonPreference)
+                screen.findPreference(getPreferenceKey());
+        mPreference.setOnClickListener(this);
+        updateState(mPreference);
+    }
+
+    @Override
+    public void onRadioButtonClicked(RadioButtonPreference preference) {
+        final int value = getDaltonizerValueToKeyMap().get(mPreferenceKey);
+        handlePreferenceChange(String.valueOf(value));
+        if (mOnChangeListener != null) {
+            mOnChangeListener.onCheckedChanged(mPreference);
+        }
+    }
+
+    private int getAccessibilityDaltonizerValue() {
+        final int daltonizerValue = getSecureAccessibilityDaltonizerValue(mContentResolver,
+                TYPE);
+        return daltonizerValue;
+    }
+
+    protected void updatePreferenceCheckedState(int value) {
+        if (mAccessibilityDaltonizerValue == value) {
+            mPreference.setChecked(true);
+        }
+    }
+
+    @Override
+    public void updateState(Preference preference) {
+        super.updateState(preference);
+        mAccessibilityDaltonizerValue = getAccessibilityDaltonizerValue();
+
+        // reset RadioButton
+        mPreference.setChecked(false);
+        final int preferenceValue = getDaltonizerValueToKeyMap().get(mPreference.getKey());
+        updatePreferenceCheckedState(preferenceValue);
+    }
+
+    /** Listener interface handles checked event. */
+    public interface OnChangeListener {
+        /** A hook that is called when preference checked. */
+        void onCheckedChanged(Preference preference);
+    }
+}
diff --git a/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java
index f127b53..3cde80a 100644
--- a/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java
@@ -36,13 +36,29 @@
 
 @SearchIndexable
 public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePreferenceFragment
-        implements DaltonizerPreferenceController.OnChangeListener,
+        implements DaltonizerRadioButtonPreferenceController.OnChangeListener,
         SwitchBar.OnSwitchChangeListener {
 
+    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+            new BaseSearchIndexProvider(R.xml.accessibility_daltonizer_settings);
     private static final String ENABLED = Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED;
-
     private static final List<AbstractPreferenceController> sControllers = new ArrayList<>();
 
+    private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
+            Lifecycle lifecycle) {
+        if (sControllers.size() == 0) {
+            final Resources resources = context.getResources();
+            final String[] daltonizerKeys = resources.getStringArray(
+                    R.array.daltonizer_mode_keys);
+
+            for (int i = 0; i < daltonizerKeys.length; i++) {
+                sControllers.add(new DaltonizerRadioButtonPreferenceController(
+                        context, lifecycle, daltonizerKeys[i]));
+            }
+        }
+        return sControllers;
+    }
+
     @Override
     public void onCheckedChanged(Preference preference) {
         for (AbstractPreferenceController controller : sControllers) {
@@ -55,8 +71,9 @@
         super.onResume();
         for (AbstractPreferenceController controller :
                 buildPreferenceControllers(getPrefContext(), getSettingsLifecycle())) {
-            ((DaltonizerPreferenceController) controller).setOnChangeListener(this);
-            ((DaltonizerPreferenceController) controller).displayPreference(getPreferenceScreen());
+            ((DaltonizerRadioButtonPreferenceController) controller).setOnChangeListener(this);
+            ((DaltonizerRadioButtonPreferenceController) controller).displayPreference(
+                    getPreferenceScreen());
         }
     }
 
@@ -65,7 +82,7 @@
         super.onPause();
         for (AbstractPreferenceController controller :
                 buildPreferenceControllers(getPrefContext(), getSettingsLifecycle())) {
-            ((DaltonizerPreferenceController) controller).setOnChangeListener(null);
+            ((DaltonizerRadioButtonPreferenceController) controller).setOnChangeListener(null);
         }
     }
 
@@ -79,7 +96,6 @@
         return R.string.help_url_color_correction;
     }
 
-
     @Override
     protected int getPreferenceScreenResId() {
         return R.xml.accessibility_daltonizer_settings;
@@ -115,22 +131,4 @@
                 Settings.Secure.getInt(getContentResolver(), ENABLED, 0) == 1);
         mSwitchBar.addOnSwitchChangeListener(this);
     }
-
-    private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
-            Lifecycle lifecycle) {
-        if (sControllers.size() == 0) {
-            final Resources resources = context.getResources();
-            final String[] daltonizerKeys = resources.getStringArray(
-                    R.array.daltonizer_mode_keys);
-
-            for (int i = 0; i < daltonizerKeys.length; i++) {
-                sControllers.add(new DaltonizerPreferenceController(
-                        context, lifecycle, daltonizerKeys[i]));
-            }
-        }
-        return sControllers;
-    }
-
-    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider(R.xml.accessibility_daltonizer_settings);
 }
diff --git a/tests/robotests/src/com/android/settings/accessibility/DaltonizerPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/DaltonizerPreferenceControllerTest.java
index 86520a8..62eb074 100644
--- a/tests/robotests/src/com/android/settings/accessibility/DaltonizerPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/DaltonizerPreferenceControllerTest.java
@@ -18,100 +18,57 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.ContentResolver;
 import android.content.Context;
 import android.provider.Settings;
 
-import androidx.preference.Preference;
-import androidx.preference.PreferenceScreen;
-
-import com.android.settingslib.core.lifecycle.Lifecycle;
-import com.android.settingslib.widget.RadioButtonPreference;
+import com.android.settings.R;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
 
 @RunWith(RobolectricTestRunner.class)
-public class DaltonizerPreferenceControllerTest implements
-        DaltonizerPreferenceController.OnChangeListener {
-    private static final String PREF_KEY = "daltonizer_mode_protanomaly";
-    private static final String PREF_VALUE = "11";
-    private static final String PREF_FAKE_VALUE = "-1";
+public class DaltonizerPreferenceControllerTest {
+    private static final String PREF_KEY = "daltonizer_preference";
+    private static final int ON = 1;
+    private static final int OFF = 0;
+    private static final String DALTONIZER_VALUE = "11";
 
-    private DaltonizerPreferenceController mController;
-
-    @Mock
-    private RadioButtonPreference mMockPref;
     private Context mContext;
-    private ContentResolver mContentResolver;
-
-    @Mock
-    private PreferenceScreen mScreen;
+    private DaltonizerPreferenceController mController;
 
     @Before
     public void setUp() {
-        MockitoAnnotations.initMocks(this);
         mContext = RuntimeEnvironment.application;
-        mController = new DaltonizerPreferenceController(mContext, mock(Lifecycle.class), PREF_KEY);
-        mController.setOnChangeListener(this);
-        mContentResolver = mContext.getContentResolver();
-
-        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mMockPref);
-        when(mMockPref.getKey()).thenReturn(PREF_KEY);
-        mController.displayPreference(mScreen);
-    }
-
-    @Override
-    public void onCheckedChanged(Preference preference) {
-        mController.updateState(preference);
+        mController = new DaltonizerPreferenceController(mContext, PREF_KEY);
     }
 
     @Test
-    public void isAvailable() {
-        assertThat(mController.isAvailable()).isTrue();
+    public void getSummary_enabledColorCorrection_shouldReturnOnSummary() {
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, ON);
+
+        assertThat(mController.getSummary().toString().contains(
+                mContext.getText(R.string.accessibility_feature_state_on))).isTrue();
     }
 
     @Test
-    public void updateState_notChecked() {
-        Settings.Secure.putString(mContentResolver,
-                Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, PREF_FAKE_VALUE);
+    public void getSummary_disabledColorCorrection_shouldReturnOffSummary() {
+        Settings.Secure.putInt(mContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, OFF);
 
-        mController.updateState(mMockPref);
-
-        // the first checked state is set to false by control
-        verify(mMockPref, atLeastOnce()).setChecked(false);
-        verify(mMockPref, never()).setChecked(true);
+        assertThat(mController.getSummary().toString().contains(
+                mContext.getText(R.string.accessibility_feature_state_off))).isTrue();
     }
 
     @Test
-    public void updateState_checked() {
-        Settings.Secure.putString(mContentResolver,
-                Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, PREF_VALUE);
+    public void getSummary_selectProtanomaly_shouldReturnProtanomalySummary() {
+        Settings.Secure.putString(mContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, DALTONIZER_VALUE);
 
-        mController.updateState(mMockPref);
-
-        // the first checked state is set to false by control
-        verify(mMockPref, atLeastOnce()).setChecked(false);
-        verify(mMockPref, atLeastOnce()).setChecked(true);
-    }
-
-    @Test
-    public void onRadioButtonClick_shouldReturnDaltonizerValue() {
-        mController.onRadioButtonClicked(mMockPref);
-        final String accessibilityDaltonizerValue = Settings.Secure.getString(mContentResolver,
-                Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER);
-
-        assertThat(accessibilityDaltonizerValue).isEqualTo(PREF_VALUE);
+        assertThat(mController.getSummary().toString().contains(
+                mContext.getText(R.string.daltonizer_mode_protanomaly))).isTrue();
     }
 }
diff --git a/tests/robotests/src/com/android/settings/accessibility/DaltonizerRadioButtonPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/DaltonizerRadioButtonPreferenceControllerTest.java
new file mode 100644
index 0000000..5ec4bf4
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/DaltonizerRadioButtonPreferenceControllerTest.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.accessibility;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.provider.Settings;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.widget.RadioButtonPreference;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(RobolectricTestRunner.class)
+public class DaltonizerRadioButtonPreferenceControllerTest implements
+        DaltonizerRadioButtonPreferenceController.OnChangeListener {
+    private static final String PREF_KEY = "daltonizer_mode_protanomaly";
+    private static final String PREF_VALUE = "11";
+    private static final String PREF_FAKE_VALUE = "-1";
+
+    private DaltonizerRadioButtonPreferenceController mController;
+
+    @Mock
+    private RadioButtonPreference mMockPref;
+    private Context mContext;
+
+    @Mock
+    private PreferenceScreen mScreen;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
+        mController = new DaltonizerRadioButtonPreferenceController(mContext, mock(Lifecycle.class),
+                PREF_KEY);
+        mController.setOnChangeListener(this);
+
+        when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mMockPref);
+        when(mMockPref.getKey()).thenReturn(PREF_KEY);
+        mController.displayPreference(mScreen);
+    }
+
+    @Override
+    public void onCheckedChanged(Preference preference) {
+        mController.updateState(preference);
+    }
+
+    @Test
+    public void isAvailable() {
+        assertThat(mController.isAvailable()).isTrue();
+    }
+
+    @Test
+    public void updateState_notChecked() {
+        Settings.Secure.putString(mContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, PREF_FAKE_VALUE);
+
+        mController.updateState(mMockPref);
+
+        // the first checked state is set to false by control
+        verify(mMockPref, atLeastOnce()).setChecked(false);
+        verify(mMockPref, never()).setChecked(true);
+    }
+
+    @Test
+    public void updateState_checked() {
+        Settings.Secure.putString(mContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, PREF_VALUE);
+
+        mController.updateState(mMockPref);
+
+        // the first checked state is set to false by control
+        verify(mMockPref, atLeastOnce()).setChecked(false);
+        verify(mMockPref, atLeastOnce()).setChecked(true);
+    }
+
+    @Test
+    public void onRadioButtonClick_shouldReturnDaltonizerValue() {
+        mController.onRadioButtonClicked(mMockPref);
+        final String accessibilityDaltonizerValue = Settings.Secure.getString(
+                mContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER);
+
+        assertThat(accessibilityDaltonizerValue).isEqualTo(PREF_VALUE);
+    }
+}
