1 package com.android.settings.display;
2 
3 import static org.mockito.Mockito.doReturn;
4 import static org.mockito.Mockito.reset;
5 import static org.mockito.Mockito.spy;
6 import static org.mockito.Mockito.verify;
7 import static org.mockito.Mockito.when;
8 import static com.google.common.truth.Truth.assertThat;
9 
10 
11 import android.content.ContentResolver;
12 import android.content.Context;
13 import android.hardware.display.ColorDisplayManager;
14 import android.provider.Settings;
15 
16 import androidx.preference.Preference;
17 import androidx.preference.PreferenceScreen;
18 
19 import com.android.settings.testutils.shadow.SettingsShadowResources;
20 import org.junit.After;
21 import org.junit.Before;
22 import org.junit.Test;
23 import org.junit.runner.RunWith;
24 import org.mockito.Answers;
25 import org.mockito.Mock;
26 import org.mockito.MockitoAnnotations;
27 import org.robolectric.RobolectricTestRunner;
28 import org.robolectric.RuntimeEnvironment;
29 import org.robolectric.annotation.Config;
30 
31 @RunWith(RobolectricTestRunner.class)
32 @Config(shadows = {
33     SettingsShadowResources.class
34 })
35 public class DisplayWhiteBalancePreferenceControllerTest {
36 
37   private DisplayWhiteBalancePreferenceController mController;
38 
39   @Mock
40   private ColorDisplayManager mColorDisplayManager;
41   private ContentResolver mContentResolver;
42   @Mock(answer = Answers.RETURNS_DEEP_STUBS)
43   private Context mContext;
44   @Mock
45   private PreferenceScreen mScreen;
46   @Mock
47   private Preference mPreference;
48 
49   private final String PREFERENCE_KEY = "display_white_balance";
50 
51   @After
tearDown()52   public void tearDown() {
53     SettingsShadowResources.reset();
54   }
55 
56   @Before
setUp()57   public void setUp() {
58     MockitoAnnotations.initMocks(this);
59 
60     mContentResolver = RuntimeEnvironment.application.getContentResolver();
61     when(mContext.getContentResolver()).thenReturn(mContentResolver);
62     when(mContext.getResources()).thenReturn(RuntimeEnvironment.application.getResources());
63     when(mScreen.findPreference(PREFERENCE_KEY)).thenReturn(mPreference);
64 
65     mController = spy(new DisplayWhiteBalancePreferenceController(mContext, PREFERENCE_KEY));
66     doReturn(mColorDisplayManager).when(mController).getColorDisplayManager();
67   }
68 
69   @Test
isAvailable()70   public void isAvailable() {
71     SettingsShadowResources.overrideResource(
72         com.android.internal.R.bool.config_displayWhiteBalanceAvailable, true);
73 
74     assertThat(mController.isAvailable()).isTrue();
75   }
76 
77   @Test
isAvailable_configuredUnavailable()78   public void isAvailable_configuredUnavailable() {
79     SettingsShadowResources.overrideResource(
80         com.android.internal.R.bool.config_displayWhiteBalanceAvailable, false);
81 
82     assertThat(mController.isAvailable()).isFalse();
83   }
84 
85   @Test
setChecked_true_setSuccessfully()86   public void setChecked_true_setSuccessfully() {
87     when(mColorDisplayManager.setDisplayWhiteBalanceEnabled(true)).thenReturn(true);
88     assertThat(mController.setChecked(true)).isTrue();
89   }
90 
91   @Test
setChecked_false_setSuccessfully()92   public void setChecked_false_setSuccessfully() {
93     when(mColorDisplayManager.setDisplayWhiteBalanceEnabled(false)).thenReturn(true);
94     assertThat(mController.setChecked(false)).isTrue();
95   }
96 
97   @Test
isChecked_true()98   public void isChecked_true() {
99     when(mColorDisplayManager.isDisplayWhiteBalanceEnabled()).thenReturn(true);
100     assertThat(mController.isChecked()).isTrue();
101   }
102 
103   @Test
isChecked_false()104   public void isChecked_false() {
105     when(mColorDisplayManager.isDisplayWhiteBalanceEnabled()).thenReturn(false);
106     assertThat(mController.isChecked()).isFalse();
107   }
108 
109   @Test
onStart_configuredUnavailable()110   public void onStart_configuredUnavailable() {
111     SettingsShadowResources.overrideResource(
112         com.android.internal.R.bool.config_displayWhiteBalanceAvailable, false);
113     mController.displayPreference(mScreen);
114     mController.onStart();
115     assertThat(mController.mContentObserver).isNull();
116   }
117 
118   @Test
onStart_configuredAvailable()119   public void onStart_configuredAvailable() {
120     SettingsShadowResources.overrideResource(
121         com.android.internal.R.bool.config_displayWhiteBalanceAvailable, true);
122     when(mColorDisplayManager.getColorMode())
123         .thenReturn(ColorDisplayManager.COLOR_MODE_NATURAL);
124     toggleAccessibilityInversion(false);
125     toggleAccessibilityDaltonizer(false);
126 
127     mController.displayPreference(mScreen);
128     mController.onStart();
129     assertThat(mController.mContentObserver).isNotNull();
130   }
131 
132   @Test
visibility_configuredAvailableAccessibilityToggled()133   public void visibility_configuredAvailableAccessibilityToggled() {
134     SettingsShadowResources.overrideResource(
135         com.android.internal.R.bool.config_displayWhiteBalanceAvailable, true);
136     mController.displayPreference(mScreen);
137 
138     // Accessibility features disabled
139     toggleAccessibilityInversion(false);
140     reset(mPreference);
141     mController.updateVisibility();
142     verify(mPreference).setVisible(true);
143 
144     toggleAccessibilityDaltonizer(false);
145     reset(mPreference);
146     mController.updateVisibility();
147     verify(mPreference).setVisible(true);
148 
149     // Accessibility features enabled one by one
150     toggleAccessibilityInversion(true);
151     mController.updateVisibility();
152     verify(mPreference).setVisible(false);
153 
154     toggleAccessibilityDaltonizer(true);
155     reset(mPreference);
156     mController.updateVisibility();
157     verify(mPreference).setVisible(false);
158 
159     // Accessibility features disabled one by one
160     toggleAccessibilityInversion(false);
161     reset(mPreference);
162     mController.updateVisibility();
163     // Daltonizer is still enabled, so we expect the preference to still be invisible
164     verify(mPreference).setVisible(false);
165 
166     // Now both a11y features are disabled, so we expect the preference to become visible
167     toggleAccessibilityDaltonizer(false);
168     mController.updateVisibility();
169     verify(mPreference).setVisible(true);
170   }
171 
172   @Test
visibility_configuredAvailableColorModeChanged()173   public void visibility_configuredAvailableColorModeChanged() {
174     SettingsShadowResources.overrideResource(
175             com.android.internal.R.bool.config_displayWhiteBalanceAvailable, true);
176     mController.displayPreference(mScreen);
177 
178     // Non-Saturated color mode selected
179     when(mColorDisplayManager.getColorMode()).thenReturn(ColorDisplayManager.COLOR_MODE_NATURAL);
180     reset(mPreference);
181     mController.updateVisibility();
182     verify(mPreference).setVisible(true);
183 
184     // Saturated color mode selected
185     when(mColorDisplayManager.getColorMode()).thenReturn(ColorDisplayManager.COLOR_MODE_SATURATED);
186     mController.updateVisibility();
187     verify(mPreference).setVisible(false);
188 
189     // Switch back to non-Saturated color mode
190     when(mColorDisplayManager.getColorMode()).thenReturn(ColorDisplayManager.COLOR_MODE_NATURAL);
191     reset(mPreference);
192     mController.updateVisibility();
193     verify(mPreference).setVisible(true);
194   }
195 
toggleAccessibilityInversion(boolean enable)196   private void toggleAccessibilityInversion(boolean enable) {
197     Settings.Secure.putInt(mContentResolver,
198         Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, enable ? 1 : 0);
199   }
200 
toggleAccessibilityDaltonizer(boolean enable)201   private void toggleAccessibilityDaltonizer(boolean enable) {
202     Settings.Secure.putInt(mContentResolver,
203         Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, enable ? 1 : 0);
204   }
205 }
206