1 /* 2 * Copyright (C) 2022 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.ToggleDaltonizerPreferenceFragment.KEY_DEUTERANOMALY; 22 import static com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment.KEY_GRAYSCALE; 23 import static com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment.KEY_PROTANOMALY; 24 import static com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment.KEY_TRITANOMEALY; 25 import static com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment.KEY_USE_SERVICE_PREFERENCE; 26 27 import static com.google.common.truth.Truth.assertThat; 28 29 import static org.mockito.Mockito.doReturn; 30 import static org.mockito.Mockito.mock; 31 import static org.mockito.Mockito.spy; 32 import static org.mockito.Mockito.when; 33 34 import android.app.settings.SettingsEnums; 35 import android.content.ComponentName; 36 import android.content.Context; 37 import android.os.Bundle; 38 import android.platform.test.annotations.DisableFlags; 39 import android.platform.test.flag.junit.SetFlagsRule; 40 import android.provider.Settings; 41 import android.view.LayoutInflater; 42 import android.view.View; 43 import android.view.ViewGroup; 44 import android.view.accessibility.Flags; 45 import android.widget.PopupWindow; 46 47 import androidx.fragment.app.FragmentActivity; 48 import androidx.preference.PreferenceManager; 49 import androidx.preference.PreferenceScreen; 50 import androidx.test.core.app.ApplicationProvider; 51 52 import com.android.settings.R; 53 import com.android.settings.accessibility.AccessibilityUtil.QuickSettingsTooltipType; 54 import com.android.settings.testutils.XmlTestUtils; 55 import com.android.settings.testutils.shadow.ShadowFragment; 56 import com.android.settings.widget.SettingsMainSwitchPreference; 57 import com.android.settingslib.widget.SelectorWithWidgetPreference; 58 59 import org.junit.Before; 60 import org.junit.Rule; 61 import org.junit.Test; 62 import org.junit.runner.RunWith; 63 import org.mockito.Answers; 64 import org.mockito.Mock; 65 import org.mockito.MockitoAnnotations; 66 import org.robolectric.RobolectricTestRunner; 67 import org.robolectric.annotation.Config; 68 import org.robolectric.shadow.api.Shadow; 69 import org.robolectric.shadows.ShadowApplication; 70 71 import java.util.List; 72 73 /** Tests for {@link ToggleDaltonizerPreferenceFragment} */ 74 @RunWith(RobolectricTestRunner.class) 75 @Config(shadows = ShadowFragment.class) 76 public class ToggleDaltonizerPreferenceFragmentTest { 77 @Rule 78 public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); 79 private final Context mContext = ApplicationProvider.getApplicationContext(); 80 private TestToggleDaltonizerPreferenceFragment mFragment; 81 private PreferenceScreen mScreen; 82 private SettingsMainSwitchPreference mSwitchPreference; 83 84 @Mock(answer = Answers.RETURNS_DEEP_STUBS) 85 private PreferenceManager mPreferenceManager; 86 @Mock 87 private SelectorWithWidgetPreference mMockDeuteranomalyPref; 88 @Mock 89 private SelectorWithWidgetPreference mMockProtanomalyPref; 90 @Mock 91 private SelectorWithWidgetPreference mMockTritanomalyPref; 92 @Mock 93 private SelectorWithWidgetPreference mMockGrayscalePref; 94 @Mock 95 private FragmentActivity mActivity; 96 97 @Before setUpTestFragment()98 public void setUpTestFragment() { 99 MockitoAnnotations.initMocks(this); 100 101 mFragment = spy(new TestToggleDaltonizerPreferenceFragment(mContext)); 102 when(mFragment.getPreferenceManager()).thenReturn(mPreferenceManager); 103 when(mFragment.getPreferenceManager().getContext()).thenReturn(mContext); 104 when(mFragment.getContext()).thenReturn(mContext); 105 when(mFragment.getActivity()).thenReturn(mActivity); 106 when(mActivity.getContentResolver()).thenReturn(mContext.getContentResolver()); 107 108 mScreen = spy(new PreferenceScreen(mContext, /* attrs= */ null)); 109 when(mScreen.findPreference(KEY_USE_SERVICE_PREFERENCE)) 110 .thenReturn(mFragment.mToggleServiceSwitchPreference); 111 when(mScreen.findPreference(KEY_DEUTERANOMALY)).thenReturn(mMockDeuteranomalyPref); 112 when(mMockDeuteranomalyPref.getKey()).thenReturn(KEY_DEUTERANOMALY); 113 when(mScreen.findPreference(KEY_PROTANOMALY)).thenReturn(mMockProtanomalyPref); 114 when(mMockProtanomalyPref.getKey()).thenReturn(KEY_PROTANOMALY); 115 when(mScreen.findPreference(KEY_TRITANOMEALY)).thenReturn(mMockTritanomalyPref); 116 when(mMockTritanomalyPref.getKey()).thenReturn(KEY_TRITANOMEALY); 117 when(mScreen.findPreference(KEY_GRAYSCALE)).thenReturn(mMockGrayscalePref); 118 when(mMockGrayscalePref.getKey()).thenReturn(KEY_GRAYSCALE); 119 when(mScreen.getPreferenceManager()).thenReturn(mPreferenceManager); 120 doReturn(mScreen).when(mFragment).getPreferenceScreen(); 121 122 mSwitchPreference = mScreen.findPreference(KEY_USE_SERVICE_PREFERENCE); 123 } 124 125 @Test onResume_colorCorrectEnabled_shouldReturnTrue()126 public void onResume_colorCorrectEnabled_shouldReturnTrue() { 127 Settings.Secure.putInt(mContext.getContentResolver(), 128 Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, ON); 129 mFragment.onAttach(mContext); 130 mFragment.onCreate(Bundle.EMPTY); 131 132 mFragment.onResume(); 133 134 assertThat(mSwitchPreference.isChecked()).isTrue(); 135 } 136 137 @Test onResume_colorCorrectDisabled_shouldReturnFalse()138 public void onResume_colorCorrectDisabled_shouldReturnFalse() { 139 Settings.Secure.putInt(mContext.getContentResolver(), 140 Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, OFF); 141 mFragment.onAttach(mContext); 142 mFragment.onCreate(Bundle.EMPTY); 143 144 mFragment.onResume(); 145 146 assertThat(mSwitchPreference.isChecked()).isFalse(); 147 } 148 149 @Test onResume_colorCorrectEnabled_switchPreferenceChecked_notShowTooltips()150 public void onResume_colorCorrectEnabled_switchPreferenceChecked_notShowTooltips() { 151 Settings.Secure.putInt(mContext.getContentResolver(), 152 Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, ON); 153 mSwitchPreference.setChecked(true); 154 mFragment.onAttach(mContext); 155 mFragment.onCreate(Bundle.EMPTY); 156 157 mFragment.onResume(); 158 159 assertThat(getLatestPopupWindow()).isNull(); 160 } 161 162 @Test 163 @DisableFlags(Flags.FLAG_A11Y_QS_SHORTCUT) onPreferenceToggled_colorCorrectDisabled_shouldReturnTrueAndShowTooltipView()164 public void onPreferenceToggled_colorCorrectDisabled_shouldReturnTrueAndShowTooltipView() { 165 Settings.Secure.putInt(mContext.getContentResolver(), 166 Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, OFF); 167 mSwitchPreference.setChecked(false); 168 mFragment.onAttach(mContext); 169 mFragment.onCreateView(LayoutInflater.from(mContext), mock(ViewGroup.class), Bundle.EMPTY); 170 mFragment.onViewCreated(mFragment.getView(), Bundle.EMPTY); 171 172 mFragment.onPreferenceToggled(mSwitchPreference.getKey(), true); 173 174 final boolean isEnabled = Settings.Secure.getInt(mContext.getContentResolver(), 175 Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, OFF) == ON; 176 assertThat(isEnabled).isTrue(); 177 assertThat(getLatestPopupWindow()).isNotNull(); 178 assertThat(getLatestPopupWindow().isShowing()).isTrue(); 179 } 180 181 @Test onPreferenceToggled_colorCorrectEnabled_shouldReturnFalseAndNotShowTooltipView()182 public void onPreferenceToggled_colorCorrectEnabled_shouldReturnFalseAndNotShowTooltipView() { 183 Settings.Secure.putInt(mContext.getContentResolver(), 184 Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, ON); 185 mSwitchPreference.setChecked(true); 186 mFragment.onAttach(mContext); 187 mFragment.onCreate(Bundle.EMPTY); 188 189 mFragment.onPreferenceToggled(mSwitchPreference.getKey(), false); 190 191 final boolean isEnabled = Settings.Secure.getInt(mContext.getContentResolver(), 192 Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, OFF) == ON; 193 assertThat(isEnabled).isFalse(); 194 assertThat(getLatestPopupWindow()).isNull(); 195 } 196 197 @Test getMetricsCategory_returnsCorrectCategory()198 public void getMetricsCategory_returnsCorrectCategory() { 199 assertThat(mFragment.getMetricsCategory()).isEqualTo( 200 SettingsEnums.ACCESSIBILITY_TOGGLE_DALTONIZER); 201 } 202 203 @Test getPreferenceScreenResId_returnsCorrectXml()204 public void getPreferenceScreenResId_returnsCorrectXml() { 205 assertThat(mFragment.getPreferenceScreenResId()).isEqualTo( 206 R.xml.accessibility_daltonizer_settings); 207 } 208 209 @Test getHelpResource_returnsCorrectHelpResource()210 public void getHelpResource_returnsCorrectHelpResource() { 211 assertThat(mFragment.getHelpResource()).isEqualTo(R.string.help_url_color_correction); 212 } 213 214 @Test getNonIndexableKeys_existInXmlLayout()215 public void getNonIndexableKeys_existInXmlLayout() { 216 final List<String> niks = ToggleDaltonizerPreferenceFragment.SEARCH_INDEX_DATA_PROVIDER 217 .getNonIndexableKeys(mContext); 218 final List<String> keys = 219 XmlTestUtils.getKeysFromPreferenceXml(mContext, 220 R.xml.accessibility_daltonizer_settings); 221 222 assertThat(keys).containsAtLeastElementsIn(niks); 223 } 224 getLatestPopupWindow()225 private static PopupWindow getLatestPopupWindow() { 226 final ShadowApplication shadowApplication = 227 Shadow.extract(ApplicationProvider.getApplicationContext()); 228 return shadowApplication.getLatestPopupWindow(); 229 } 230 231 private static class TestToggleDaltonizerPreferenceFragment extends 232 ToggleDaltonizerPreferenceFragment { 233 private static final String PLACEHOLDER_PACKAGE_NAME = "com.placeholder.example"; 234 private static final String PLACEHOLDER_CLASS_NAME = 235 PLACEHOLDER_PACKAGE_NAME + ".placeholder"; 236 private static final ComponentName PLACEHOLDER_COMPONENT_NAME = new ComponentName( 237 PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_CLASS_NAME); 238 private static final String PLACEHOLDER_TILE_TOOLTIP_CONTENT = 239 PLACEHOLDER_PACKAGE_NAME + "tooltip_content"; 240 TestToggleDaltonizerPreferenceFragment(Context context)241 TestToggleDaltonizerPreferenceFragment(Context context) { 242 super(); 243 mComponentName = PLACEHOLDER_COMPONENT_NAME; 244 final SettingsMainSwitchPreference switchPreference = 245 new SettingsMainSwitchPreference(context); 246 switchPreference.setKey(KEY_USE_SERVICE_PREFERENCE); 247 mToggleServiceSwitchPreference = switchPreference; 248 setArguments(new Bundle()); 249 } 250 251 @Override onViewCreated(View view, Bundle savedInstanceState)252 public void onViewCreated(View view, Bundle savedInstanceState) { 253 // do nothing 254 } 255 256 @Override onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)257 public View onCreateView(LayoutInflater inflater, ViewGroup container, 258 Bundle savedInstanceState) { 259 return mock(View.class); 260 } 261 262 @Override updateShortcutPreference()263 protected void updateShortcutPreference() { 264 // UI related function, do nothing in tests 265 } 266 267 @Override getTileComponentName()268 ComponentName getTileComponentName() { 269 return PLACEHOLDER_COMPONENT_NAME; 270 } 271 272 @Override getTileTooltipContent(@uickSettingsTooltipType int type)273 protected CharSequence getTileTooltipContent(@QuickSettingsTooltipType int type) { 274 return PLACEHOLDER_TILE_TOOLTIP_CONTENT; 275 } 276 277 @Override getView()278 public View getView() { 279 return mock(View.class); 280 } 281 } 282 } 283