1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings.accessibility; 18 19 import static androidx.lifecycle.Lifecycle.Event.ON_RESUME; 20 import static androidx.lifecycle.Lifecycle.Event.ON_STOP; 21 22 import static com.android.settings.core.BasePreferenceController.AVAILABLE; 23 import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE; 24 import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING; 25 26 import static com.google.common.truth.Truth.assertThat; 27 28 import static org.robolectric.Shadows.shadowOf; 29 30 import android.content.ContentResolver; 31 import android.content.Context; 32 import android.os.Looper; 33 import android.platform.test.annotations.DisableFlags; 34 import android.platform.test.annotations.EnableFlags; 35 import android.platform.test.flag.junit.SetFlagsRule; 36 import android.provider.Settings; 37 38 import androidx.lifecycle.LifecycleOwner; 39 import androidx.preference.PreferenceManager; 40 import androidx.preference.PreferenceScreen; 41 import androidx.test.core.app.ApplicationProvider; 42 43 import com.android.server.accessibility.Flags; 44 import com.android.settings.widget.SeekBarPreference; 45 import com.android.settingslib.core.lifecycle.Lifecycle; 46 47 import org.junit.After; 48 import org.junit.Before; 49 import org.junit.Rule; 50 import org.junit.Test; 51 import org.junit.runner.RunWith; 52 import org.robolectric.RobolectricTestRunner; 53 54 /** Tests for {@link DaltonizerSaturationSeekbarPreferenceController}. */ 55 @RunWith(RobolectricTestRunner.class) 56 public class DaltonizerSaturationSeekbarPreferenceControllerTest { 57 58 private ContentResolver mContentResolver; 59 private DaltonizerSaturationSeekbarPreferenceController mController; 60 61 private PreferenceScreen mScreen; 62 private LifecycleOwner mLifecycleOwner; 63 private Lifecycle mLifecycle; 64 65 private SeekBarPreference mPreference; 66 67 @Rule 68 public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); 69 70 @Before setup()71 public void setup() { 72 Context context = ApplicationProvider.getApplicationContext(); 73 mContentResolver = context.getContentResolver(); 74 75 mPreference = new SeekBarPreference(context); 76 mPreference.setKey(ToggleDaltonizerPreferenceFragment.KEY_SATURATION); 77 mScreen = new PreferenceManager(context).createPreferenceScreen(context); 78 mScreen.addPreference(mPreference); 79 80 mLifecycleOwner = () -> mLifecycle; 81 mLifecycle = new Lifecycle(mLifecycleOwner); 82 mController = new DaltonizerSaturationSeekbarPreferenceController( 83 context, 84 ToggleDaltonizerPreferenceFragment.KEY_SATURATION); 85 } 86 87 @After cleanup()88 public void cleanup() { 89 Settings.Secure.putString( 90 mContentResolver, 91 Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, 92 null); 93 Settings.Secure.putString( 94 mContentResolver, 95 Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 96 null); 97 Settings.Secure.putString( 98 mContentResolver, 99 Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_SATURATION_LEVEL, 100 null); 101 } 102 103 @Test constructor_defaultValuesMatch()104 public void constructor_defaultValuesMatch() { 105 assertThat(mController.getSliderPosition()).isEqualTo(7); 106 assertThat(mController.getMax()).isEqualTo(10); 107 assertThat(mController.getMin()).isEqualTo(1); 108 } 109 110 @Test 111 @DisableFlags(Flags.FLAG_ENABLE_COLOR_CORRECTION_SATURATION) getAvailabilityStatus_flagDisabled_unavailable()112 public void getAvailabilityStatus_flagDisabled_unavailable() { 113 assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE); 114 } 115 116 @Test 117 @EnableFlags(Flags.FLAG_ENABLE_COLOR_CORRECTION_SATURATION) getAvailabilityStatus_defaultSettings_unavailable()118 public void getAvailabilityStatus_defaultSettings_unavailable() { 119 // By default enabled == false. 120 assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING); 121 } 122 123 @Test 124 @EnableFlags(Flags.FLAG_ENABLE_COLOR_CORRECTION_SATURATION) getAvailabilityStatus_enabledDefaultDisplayMode_available()125 public void getAvailabilityStatus_enabledDefaultDisplayMode_available() { 126 setDaltonizerEnabled(1); 127 128 // By default display mode is deuteranomaly. 129 assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); 130 } 131 132 @Test 133 @EnableFlags(Flags.FLAG_ENABLE_COLOR_CORRECTION_SATURATION) getAvailabilityStatus_flagEnabledProtanEnabled_available()134 public void getAvailabilityStatus_flagEnabledProtanEnabled_available() { 135 setDaltonizerMode(/* enabled= */ 1, /* mode= */ 11); 136 assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); 137 } 138 139 @Test 140 @EnableFlags(Flags.FLAG_ENABLE_COLOR_CORRECTION_SATURATION) getAvailabilityStatus_flagEnabledDeutranEnabled_available()141 public void getAvailabilityStatus_flagEnabledDeutranEnabled_available() { 142 setDaltonizerMode(/* enabled= */ 1, /* mode= */ 12); 143 assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); 144 } 145 146 @Test 147 @EnableFlags(Flags.FLAG_ENABLE_COLOR_CORRECTION_SATURATION) getAvailabilityStatus_flagEnabledTritanEnabled_available()148 public void getAvailabilityStatus_flagEnabledTritanEnabled_available() { 149 setDaltonizerMode(/* enabled= */ 1, /* mode= */ 13); 150 assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); 151 } 152 153 @Test 154 @EnableFlags(Flags.FLAG_ENABLE_COLOR_CORRECTION_SATURATION) getAvailabilityStatus_flagEnabledGrayScale_disabled()155 public void getAvailabilityStatus_flagEnabledGrayScale_disabled() { 156 setDaltonizerMode(/* enabled= */ 1, /* mode= */ 0); 157 assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING); 158 } 159 160 @Test 161 @EnableFlags(Flags.FLAG_ENABLE_COLOR_CORRECTION_SATURATION) getAvailabilityStatus_flagEnabledColorCorrectionDisabled_disabled()162 public void getAvailabilityStatus_flagEnabledColorCorrectionDisabled_disabled() { 163 setDaltonizerMode(/* enabled= */ 0, /* mode= */ 11); 164 assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING); 165 } 166 167 @Test 168 @EnableFlags(Flags.FLAG_ENABLE_COLOR_CORRECTION_SATURATION) getAvailabilityStatus_flagEnabledColorCorrectionDisabledGrayScale_disabled()169 public void getAvailabilityStatus_flagEnabledColorCorrectionDisabledGrayScale_disabled() { 170 setDaltonizerMode(/* enabled= */ 0, /* mode= */ 0); 171 assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING); 172 } 173 174 @Test 175 @EnableFlags(Flags.FLAG_ENABLE_COLOR_CORRECTION_SATURATION) displayPreference_flagEnabledColorCorrectionEnabled_enabledWithDefaultValues()176 public void displayPreference_flagEnabledColorCorrectionEnabled_enabledWithDefaultValues() { 177 setDaltonizerMode(/* enabled= */ 1, /* mode= */ 11); 178 mController.displayPreference(mScreen); 179 180 assertThat(mPreference.isEnabled()).isTrue(); 181 assertThat(mPreference.getMax()).isEqualTo(10); 182 assertThat(mPreference.getMin()).isEqualTo(1); 183 assertThat(mPreference.getProgress()).isEqualTo(7); 184 assertThat(mPreference.isVisible()).isTrue(); 185 assertThat(mPreference.getOnPreferenceChangeListener()).isEqualTo(mController); 186 } 187 188 @Test 189 @EnableFlags(Flags.FLAG_ENABLE_COLOR_CORRECTION_SATURATION) displayPreference_flagEnabledColorCorrectionDisabled_disabledWithDefaultValues()190 public void displayPreference_flagEnabledColorCorrectionDisabled_disabledWithDefaultValues() { 191 setDaltonizerMode(/* enabled= */ 0, /* mode= */ 11); 192 mController.displayPreference(mScreen); 193 194 assertThat(mPreference.isEnabled()).isFalse(); 195 assertThat(mPreference.getMax()).isEqualTo(10); 196 assertThat(mPreference.getMin()).isEqualTo(1); 197 assertThat(mPreference.getProgress()).isEqualTo(7); 198 assertThat(mPreference.isVisible()).isTrue(); 199 assertThat(mPreference.getOnPreferenceChangeListener()).isEqualTo(mController); 200 } 201 202 @Test 203 @DisableFlags(Flags.FLAG_ENABLE_COLOR_CORRECTION_SATURATION) displayPreference_disabled_notVisible()204 public void displayPreference_disabled_notVisible() { 205 mController.displayPreference(mScreen); 206 207 assertThat(mPreference.isVisible()).isFalse(); 208 assertThat(mPreference.getOnPreferenceChangeListener()).isNull(); 209 } 210 211 @Test setSliderPosition_inRange_secureSettingsUpdated()212 public void setSliderPosition_inRange_secureSettingsUpdated() { 213 var isSliderSet = mController.setSliderPosition(9); 214 215 assertThat(isSliderSet).isTrue(); 216 assertThat(Settings.Secure.getInt( 217 mContentResolver, 218 Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_SATURATION_LEVEL, 219 7)).isEqualTo(9); 220 } 221 222 @Test setSliderPosition_min_secureSettingsUpdated()223 public void setSliderPosition_min_secureSettingsUpdated() { 224 var isSliderSet = mController.setSliderPosition(1); 225 226 assertThat(isSliderSet).isTrue(); 227 assertThat(Settings.Secure.getInt( 228 mContentResolver, 229 Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_SATURATION_LEVEL, 230 7)).isEqualTo(1); 231 } 232 233 @Test setSliderPosition_max_secureSettingsUpdated()234 public void setSliderPosition_max_secureSettingsUpdated() { 235 var isSliderSet = mController.setSliderPosition(10); 236 237 assertThat(isSliderSet).isTrue(); 238 assertThat(Settings.Secure.getInt( 239 mContentResolver, 240 Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_SATURATION_LEVEL, 241 7)).isEqualTo(10); 242 } 243 244 @Test setSliderPosition_tooLarge_secureSettingsNotUpdated()245 public void setSliderPosition_tooLarge_secureSettingsNotUpdated() { 246 var isSliderSet = mController.setSliderPosition(11); 247 248 assertThat(isSliderSet).isFalse(); 249 assertThat(Settings.Secure.getInt( 250 mContentResolver, 251 Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_SATURATION_LEVEL, 252 7)).isEqualTo(7); 253 } 254 255 @Test setSliderPosition_tooSmall_secureSettingsNotUpdated()256 public void setSliderPosition_tooSmall_secureSettingsNotUpdated() { 257 var isSliderSet = mController.setSliderPosition(-1); 258 259 assertThat(isSliderSet).isFalse(); 260 assertThat(Settings.Secure.getInt( 261 mContentResolver, 262 Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_SATURATION_LEVEL, 263 7)).isEqualTo(7); 264 } 265 266 @Test updateState_enabledProtan_preferenceEnabled()267 public void updateState_enabledProtan_preferenceEnabled() { 268 setDaltonizerMode(/* enabled= */ 1, /* mode= */ 11); 269 270 mController.updateState(mPreference); 271 272 assertThat(mPreference.isEnabled()).isTrue(); 273 } 274 275 @Test updateState_enabledDeuteran_preferenceEnabled()276 public void updateState_enabledDeuteran_preferenceEnabled() { 277 setDaltonizerMode(/* enabled= */ 1, /* mode= */ 12); 278 279 mController.updateState(mPreference); 280 281 assertThat(mPreference.isEnabled()).isTrue(); 282 } 283 284 @Test updateState_enabledTritan_preferenceEnabled()285 public void updateState_enabledTritan_preferenceEnabled() { 286 setDaltonizerMode(/* enabled= */ 1, /* mode= */ 13); 287 288 mController.updateState(mPreference); 289 290 assertThat(mPreference.isEnabled()).isTrue(); 291 } 292 293 @Test updateState_disabledGrayScale_preferenceDisabled()294 public void updateState_disabledGrayScale_preferenceDisabled() { 295 setDaltonizerMode(/* enabled= */ 0, /* mode= */ 0); 296 297 mController.updateState(mPreference); 298 299 assertThat(mPreference.isEnabled()).isFalse(); 300 } 301 302 @Test updateState_nullPreference_noError()303 public void updateState_nullPreference_noError() { 304 setDaltonizerMode(/* enabled= */ 0, /* mode= */ 0); 305 306 mController.updateState(null); 307 } 308 309 @Test updateState_enabledGrayScale_preferenceDisabled()310 public void updateState_enabledGrayScale_preferenceDisabled() { 311 setDaltonizerMode(/* enabled= */ 1, /* mode= */ 0); 312 313 mController.updateState(mPreference); 314 315 assertThat(mPreference.isEnabled()).isFalse(); 316 } 317 318 @Test onResume_daltonizerEnabledAfterResumed_preferenceEnabled()319 public void onResume_daltonizerEnabledAfterResumed_preferenceEnabled() { 320 setDaltonizerMode(/* enabled= */ 0, /* mode= */ 11); 321 mController.displayPreference(mScreen); 322 assertThat(mPreference.isEnabled()).isFalse(); 323 324 mLifecycle.addObserver(mController); 325 mLifecycle.handleLifecycleEvent(ON_RESUME); 326 327 setDaltonizerEnabled(1); 328 shadowOf(Looper.getMainLooper()).idle(); 329 330 assertThat(mPreference.isEnabled()).isTrue(); 331 } 332 333 @Test onResume_daltonizerDisabledAfterResumed_preferenceDisabled()334 public void onResume_daltonizerDisabledAfterResumed_preferenceDisabled() { 335 setDaltonizerMode(/* enabled= */ 1, /* mode= */ 11); 336 mController.displayPreference(mScreen); 337 assertThat(mPreference.isEnabled()).isTrue(); 338 339 mLifecycle.addObserver(mController); 340 mLifecycle.handleLifecycleEvent(ON_RESUME); 341 342 setDaltonizerEnabled(0); 343 shadowOf(Looper.getMainLooper()).idle(); 344 345 assertThat(mPreference.isEnabled()).isFalse(); 346 } 347 348 @Test onResume_daltonizerGrayScaledAfterResumed_preferenceDisabled()349 public void onResume_daltonizerGrayScaledAfterResumed_preferenceDisabled() { 350 setDaltonizerMode(/* enabled= */ 1, /* mode= */ 11); 351 mController.displayPreference(mScreen); 352 assertThat(mPreference.isEnabled()).isTrue(); 353 354 mLifecycle.addObserver(mController); 355 mLifecycle.handleLifecycleEvent(ON_RESUME); 356 357 setDaltonizerDisplay(0); 358 shadowOf(Looper.getMainLooper()).idle(); 359 360 assertThat(mPreference.isEnabled()).isFalse(); 361 } 362 363 @Test onStop_daltonizerEnabledAfterOnStop_preferenceNotChanged()364 public void onStop_daltonizerEnabledAfterOnStop_preferenceNotChanged() { 365 setDaltonizerMode(/* enabled= */ 0, /* mode= */ 11); 366 mController.displayPreference(mScreen); 367 assertThat(mPreference.isEnabled()).isFalse(); 368 369 mLifecycle.addObserver(mController); 370 mLifecycle.handleLifecycleEvent(ON_STOP); 371 372 // enabled. 373 setDaltonizerEnabled(1); 374 shadowOf(Looper.getMainLooper()).idle(); 375 376 assertThat(mPreference.isEnabled()).isFalse(); 377 } 378 setDaltonizerMode(int enabled, int mode)379 private void setDaltonizerMode(int enabled, int mode) { 380 setDaltonizerEnabled(enabled); 381 setDaltonizerDisplay(mode); 382 } 383 setDaltonizerEnabled(int enabled)384 private void setDaltonizerEnabled(int enabled) { 385 Settings.Secure.putInt( 386 mContentResolver, 387 Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 388 enabled); 389 } 390 setDaltonizerDisplay(int mode)391 private void setDaltonizerDisplay(int mode) { 392 Settings.Secure.putString( 393 mContentResolver, 394 Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, 395 Integer.toString(mode)); 396 } 397 } 398