Loading res/values/arrays.xml +7 −0 Original line number Diff line number Diff line Loading @@ -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> Loading src/com/android/settings/accessibility/DaltonizerPreferenceController.java +25 −121 Original line number Diff line number Diff line Loading @@ -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 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; // pair the preference key and daltonizer value. private final Map<String, Integer> mAccessibilityDaltonizerKeyToValueMap = new HashMap<>(); /** Controller that shows and updates the color correction summary. */ public class DaltonizerPreferenceController extends BasePreferenceController { // 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; private static final String DALTONIZER_TYPE = Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER; private static final String DALTONIZER_ENABLED = Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED; 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 Loading @@ -109,50 +41,22 @@ public class DaltonizerPreferenceController extends BasePreferenceController imp } @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(); 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]; // reset RadioButton mPreference.setChecked(false); final int preferenceValue = getDaltonizerValueToKeyMap().get(mPreference.getKey()); updatePreferenceCheckedState(preferenceValue); } final CharSequence serviceState = AccessibilityUtil.getSummary(mContext, DALTONIZER_ENABLED); /** Listener interface handles checked event. */ public interface OnChangeListener { /** A hook that is called when preference checked.*/ void onCheckedChanged(Preference preference); return mContext.getString( R.string.preference_summary_default_combination, serviceState, serviceSummary); } } src/com/android/settings/accessibility/DaltonizerRadioButtonPreferenceController.java 0 → 100644 +165 −0 Original line number Diff line number Diff line /* * 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); } } src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java +22 −24 Original line number Diff line number Diff line Loading @@ -36,13 +36,29 @@ import java.util.List; @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) { Loading @@ -55,8 +71,9 @@ public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePrefe super.onResume(); for (AbstractPreferenceController controller : buildPreferenceControllers(getPrefContext(), getSettingsLifecycle())) { ((DaltonizerPreferenceController) controller).setOnChangeListener(this); ((DaltonizerPreferenceController) controller).displayPreference(getPreferenceScreen()); ((DaltonizerRadioButtonPreferenceController) controller).setOnChangeListener(this); ((DaltonizerRadioButtonPreferenceController) controller).displayPreference( getPreferenceScreen()); } } Loading @@ -65,7 +82,7 @@ public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePrefe super.onPause(); for (AbstractPreferenceController controller : buildPreferenceControllers(getPrefContext(), getSettingsLifecycle())) { ((DaltonizerPreferenceController) controller).setOnChangeListener(null); ((DaltonizerRadioButtonPreferenceController) controller).setOnChangeListener(null); } } Loading @@ -79,7 +96,6 @@ public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePrefe return R.string.help_url_color_correction; } @Override protected int getPreferenceScreenResId() { return R.xml.accessibility_daltonizer_settings; Loading Loading @@ -115,22 +131,4 @@ public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePrefe 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); } tests/robotests/src/com/android/settings/accessibility/DaltonizerPreferenceControllerTest.java +23 −66 Original line number Diff line number Diff line Loading @@ -18,100 +18,57 @@ 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.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"; private DaltonizerPreferenceController mController; 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"; @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); @Test public void updateState_notChecked() { Settings.Secure.putString(mContentResolver, 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); assertThat(mController.getSummary().toString().contains( mContext.getText(R.string.accessibility_feature_state_on))).isTrue(); } @Test public void updateState_checked() { Settings.Secure.putString(mContentResolver, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, PREF_VALUE); mController.updateState(mMockPref); public void getSummary_disabledColorCorrection_shouldReturnOffSummary() { Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, OFF); // the first checked state is set to false by control verify(mMockPref, atLeastOnce()).setChecked(false); verify(mMockPref, atLeastOnce()).setChecked(true); assertThat(mController.getSummary().toString().contains( mContext.getText(R.string.accessibility_feature_state_off))).isTrue(); } @Test public void onRadioButtonClick_shouldReturnDaltonizerValue() { mController.onRadioButtonClicked(mMockPref); final String accessibilityDaltonizerValue = Settings.Secure.getString(mContentResolver, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER); public void getSummary_selectProtanomaly_shouldReturnProtanomalySummary() { Settings.Secure.putString(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, DALTONIZER_VALUE); assertThat(accessibilityDaltonizerValue).isEqualTo(PREF_VALUE); assertThat(mController.getSummary().toString().contains( mContext.getText(R.string.daltonizer_mode_protanomaly))).isTrue(); } } Loading
res/values/arrays.xml +7 −0 Original line number Diff line number Diff line Loading @@ -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> Loading
src/com/android/settings/accessibility/DaltonizerPreferenceController.java +25 −121 Original line number Diff line number Diff line Loading @@ -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 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; // pair the preference key and daltonizer value. private final Map<String, Integer> mAccessibilityDaltonizerKeyToValueMap = new HashMap<>(); /** Controller that shows and updates the color correction summary. */ public class DaltonizerPreferenceController extends BasePreferenceController { // 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; private static final String DALTONIZER_TYPE = Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER; private static final String DALTONIZER_ENABLED = Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED; 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 Loading @@ -109,50 +41,22 @@ public class DaltonizerPreferenceController extends BasePreferenceController imp } @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(); 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]; // reset RadioButton mPreference.setChecked(false); final int preferenceValue = getDaltonizerValueToKeyMap().get(mPreference.getKey()); updatePreferenceCheckedState(preferenceValue); } final CharSequence serviceState = AccessibilityUtil.getSummary(mContext, DALTONIZER_ENABLED); /** Listener interface handles checked event. */ public interface OnChangeListener { /** A hook that is called when preference checked.*/ void onCheckedChanged(Preference preference); return mContext.getString( R.string.preference_summary_default_combination, serviceState, serviceSummary); } }
src/com/android/settings/accessibility/DaltonizerRadioButtonPreferenceController.java 0 → 100644 +165 −0 Original line number Diff line number Diff line /* * 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); } }
src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java +22 −24 Original line number Diff line number Diff line Loading @@ -36,13 +36,29 @@ import java.util.List; @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) { Loading @@ -55,8 +71,9 @@ public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePrefe super.onResume(); for (AbstractPreferenceController controller : buildPreferenceControllers(getPrefContext(), getSettingsLifecycle())) { ((DaltonizerPreferenceController) controller).setOnChangeListener(this); ((DaltonizerPreferenceController) controller).displayPreference(getPreferenceScreen()); ((DaltonizerRadioButtonPreferenceController) controller).setOnChangeListener(this); ((DaltonizerRadioButtonPreferenceController) controller).displayPreference( getPreferenceScreen()); } } Loading @@ -65,7 +82,7 @@ public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePrefe super.onPause(); for (AbstractPreferenceController controller : buildPreferenceControllers(getPrefContext(), getSettingsLifecycle())) { ((DaltonizerPreferenceController) controller).setOnChangeListener(null); ((DaltonizerRadioButtonPreferenceController) controller).setOnChangeListener(null); } } Loading @@ -79,7 +96,6 @@ public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePrefe return R.string.help_url_color_correction; } @Override protected int getPreferenceScreenResId() { return R.xml.accessibility_daltonizer_settings; Loading Loading @@ -115,22 +131,4 @@ public final class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePrefe 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); }
tests/robotests/src/com/android/settings/accessibility/DaltonizerPreferenceControllerTest.java +23 −66 Original line number Diff line number Diff line Loading @@ -18,100 +18,57 @@ 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.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"; private DaltonizerPreferenceController mController; 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"; @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); @Test public void updateState_notChecked() { Settings.Secure.putString(mContentResolver, 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); assertThat(mController.getSummary().toString().contains( mContext.getText(R.string.accessibility_feature_state_on))).isTrue(); } @Test public void updateState_checked() { Settings.Secure.putString(mContentResolver, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, PREF_VALUE); mController.updateState(mMockPref); public void getSummary_disabledColorCorrection_shouldReturnOffSummary() { Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, OFF); // the first checked state is set to false by control verify(mMockPref, atLeastOnce()).setChecked(false); verify(mMockPref, atLeastOnce()).setChecked(true); assertThat(mController.getSummary().toString().contains( mContext.getText(R.string.accessibility_feature_state_off))).isTrue(); } @Test public void onRadioButtonClick_shouldReturnDaltonizerValue() { mController.onRadioButtonClicked(mMockPref); final String accessibilityDaltonizerValue = Settings.Secure.getString(mContentResolver, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER); public void getSummary_selectProtanomaly_shouldReturnProtanomalySummary() { Settings.Secure.putString(mContext.getContentResolver(), Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, DALTONIZER_VALUE); assertThat(accessibilityDaltonizerValue).isEqualTo(PREF_VALUE); assertThat(mController.getSummary().toString().contains( mContext.getText(R.string.daltonizer_mode_protanomaly))).isTrue(); } }