1 /* 2 * Copyright (C) 2023 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 com.android.settings.accessibility.AccessibilityUtil.State.OFF; 20 import static com.android.settings.accessibility.AccessibilityUtil.State.ON; 21 import static com.android.settings.accessibility.FlashNotificationsUtil.DEFAULT_SCREEN_FLASH_COLOR; 22 import static com.android.settings.core.BasePreferenceController.AVAILABLE; 23 24 import static com.google.common.truth.Truth.assertThat; 25 26 import static org.mockito.ArgumentMatchers.any; 27 import static org.mockito.ArgumentMatchers.anyString; 28 import static org.mockito.Mockito.verify; 29 import static org.mockito.Mockito.when; 30 31 import android.content.ContentResolver; 32 import android.content.Context; 33 import android.graphics.Color; 34 import android.provider.Settings; 35 36 import androidx.fragment.app.Fragment; 37 import androidx.fragment.app.FragmentActivity; 38 import androidx.fragment.app.FragmentManager; 39 import androidx.preference.Preference; 40 import androidx.preference.PreferenceScreen; 41 42 import com.android.settings.R; 43 44 import org.junit.After; 45 import org.junit.Before; 46 import org.junit.Rule; 47 import org.junit.Test; 48 import org.junit.runner.RunWith; 49 import org.mockito.Mock; 50 import org.mockito.MockitoAnnotations; 51 import org.mockito.junit.MockitoJUnit; 52 import org.mockito.junit.MockitoRule; 53 import org.robolectric.Robolectric; 54 import org.robolectric.RobolectricTestRunner; 55 import org.robolectric.annotation.Config; 56 import org.robolectric.annotation.Implementation; 57 import org.robolectric.annotation.Implements; 58 import org.robolectric.annotation.Resetter; 59 60 import java.util.function.Consumer; 61 62 @RunWith(RobolectricTestRunner.class) 63 @Config(shadows = { 64 ScreenFlashNotificationPreferenceControllerTest 65 .ShadowScreenFlashNotificationColorDialogFragment.class, 66 ShadowFlashNotificationsUtils.class, 67 com.android.settings.testutils.shadow.ShadowFragment.class, 68 }) 69 public class ScreenFlashNotificationPreferenceControllerTest { 70 private static final String PREFERENCE_KEY = "preference_key"; 71 private static final String COLOR_DESCRIPTION_TEXT = "Colorful"; 72 73 @Rule 74 public MockitoRule mMockitoRule = MockitoJUnit.rule(); 75 76 @Mock 77 private PreferenceScreen mPreferenceScreen; 78 @Mock 79 private Preference mPreference; 80 @Mock 81 private Fragment mParentFragment; 82 @Mock 83 private FragmentManager mFragmentManager; 84 @Mock 85 private ScreenFlashNotificationColorDialogFragment mDialogFragment; 86 87 private ScreenFlashNotificationPreferenceController mController; 88 private ContentResolver mContentResolver; 89 90 @Before setUp()91 public void setUp() { 92 MockitoAnnotations.initMocks(this); 93 FragmentActivity fragmentActivity = Robolectric.setupActivity(FragmentActivity.class); 94 Context context = fragmentActivity.getApplicationContext(); 95 ShadowScreenFlashNotificationColorDialogFragment.setInstance(mDialogFragment); 96 ShadowFlashNotificationsUtils.setColorDescriptionText(COLOR_DESCRIPTION_TEXT); 97 98 mContentResolver = context.getContentResolver(); 99 mController = new ScreenFlashNotificationPreferenceController(context, PREFERENCE_KEY); 100 when(mPreferenceScreen.findPreference(PREFERENCE_KEY)).thenReturn(mPreference); 101 when(mPreference.getKey()).thenReturn(PREFERENCE_KEY); 102 mController.setParentFragment(mParentFragment); 103 when(mParentFragment.getParentFragmentManager()).thenReturn(mFragmentManager); 104 } 105 106 @After tearDown()107 public void tearDown() { 108 ShadowScreenFlashNotificationColorDialogFragment.reset(); 109 } 110 111 @Test getAvailabilityStatus()112 public void getAvailabilityStatus() { 113 assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); 114 } 115 116 @Test isChecked_setOff_assertFalse()117 public void isChecked_setOff_assertFalse() { 118 Settings.System.putInt(mContentResolver, Settings.System.SCREEN_FLASH_NOTIFICATION, OFF); 119 assertThat(mController.isChecked()).isFalse(); 120 } 121 122 @Test isChecked_setOn_assertTrue()123 public void isChecked_setOn_assertTrue() { 124 Settings.System.putInt(mContentResolver, Settings.System.SCREEN_FLASH_NOTIFICATION, ON); 125 assertThat(mController.isChecked()).isTrue(); 126 } 127 128 @Test setChecked_whenTransparentColor_setTrue_assertNotTransparentColor()129 public void setChecked_whenTransparentColor_setTrue_assertNotTransparentColor() { 130 Settings.System.putInt(mContentResolver, 131 Settings.System.SCREEN_FLASH_NOTIFICATION_COLOR, Color.TRANSPARENT); 132 mController.setChecked(true); 133 assertThat(Settings.System.getInt(mContentResolver, 134 Settings.System.SCREEN_FLASH_NOTIFICATION_COLOR, 0)).isEqualTo( 135 DEFAULT_SCREEN_FLASH_COLOR); 136 } 137 138 @Test setChecked_whenNotTransparent_setTrue_assertSameColor()139 public void setChecked_whenNotTransparent_setTrue_assertSameColor() { 140 Settings.System.putInt(mContentResolver, 141 Settings.System.SCREEN_FLASH_NOTIFICATION_COLOR, 0x4D0000FF); 142 mController.setChecked(true); 143 assertThat(Settings.System.getInt(mContentResolver, 144 Settings.System.SCREEN_FLASH_NOTIFICATION_COLOR, 0)) 145 .isEqualTo(0x4D0000FF); 146 } 147 148 @Test setChecked_setTrue_assertOn()149 public void setChecked_setTrue_assertOn() { 150 mController.setChecked(true); 151 assertThat( 152 Settings.System.getInt(mContentResolver, Settings.System.SCREEN_FLASH_NOTIFICATION, 153 OFF)).isEqualTo(ON); 154 } 155 156 @Test setChecked_setFalse_assertOff()157 public void setChecked_setFalse_assertOff() { 158 mController.setChecked(false); 159 assertThat( 160 Settings.System.getInt(mContentResolver, Settings.System.SCREEN_FLASH_NOTIFICATION, 161 OFF)).isEqualTo(OFF); 162 } 163 164 @Test getSliceHighlightMenuRes()165 public void getSliceHighlightMenuRes() { 166 assertThat(mController.getSliceHighlightMenuRes()) 167 .isEqualTo(R.string.menu_key_accessibility); 168 } 169 170 @Test getSummary()171 public void getSummary() { 172 assertThat(mController.getSummary()).isEqualTo(COLOR_DESCRIPTION_TEXT); 173 } 174 175 @Test displayPreference()176 public void displayPreference() { 177 mController.displayPreference(mPreferenceScreen); 178 verify(mPreference).setSummary(COLOR_DESCRIPTION_TEXT); 179 } 180 181 @Test handlePreferenceTreeClick()182 public void handlePreferenceTreeClick() { 183 mController.handlePreferenceTreeClick(mPreference); 184 verify(mDialogFragment).show(any(FragmentManager.class), anyString()); 185 } 186 187 /** 188 * Note: Actually, shadow of ScreenFlashNotificationColorDialogFragment will not be used. 189 * Instance that returned with {@link #getInstance} should be set with {@link #setInstance} 190 */ 191 @Implements(ScreenFlashNotificationColorDialogFragment.class) 192 public static class ShadowScreenFlashNotificationColorDialogFragment { 193 static ScreenFlashNotificationColorDialogFragment sInstance = null; 194 195 @Implementation getInstance( int initialColor, Consumer<Integer> colorConsumer)196 protected static ScreenFlashNotificationColorDialogFragment getInstance( 197 int initialColor, Consumer<Integer> colorConsumer) { 198 return sInstance; 199 } 200 setInstance(ScreenFlashNotificationColorDialogFragment instance)201 public static void setInstance(ScreenFlashNotificationColorDialogFragment instance) { 202 sInstance = instance; 203 } 204 205 @Resetter reset()206 public static void reset() { 207 sInstance = null; 208 } 209 } 210 } 211