1 /* 2 * Copyright (C) 2019 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.ON; 20 import static com.android.settings.accessibility.MagnificationCapabilities.MagnificationMode; 21 import static com.android.settings.accessibility.MagnificationModePreferenceController.MagnificationModeInfo; 22 23 import static com.google.common.truth.Truth.assertThat; 24 25 import static org.mockito.Mockito.never; 26 import static org.mockito.Mockito.verify; 27 28 import android.app.Dialog; 29 import android.content.Context; 30 import android.content.DialogInterface; 31 import android.os.Bundle; 32 import android.provider.Settings; 33 import android.text.SpannableString; 34 import android.text.TextUtils; 35 import android.view.View; 36 import android.widget.AdapterView; 37 import android.widget.ListView; 38 import android.widget.TextView; 39 40 import androidx.preference.Preference; 41 import androidx.preference.PreferenceManager; 42 import androidx.preference.PreferenceScreen; 43 import androidx.test.core.app.ApplicationProvider; 44 45 import com.android.settings.DialogCreatable; 46 import com.android.settings.R; 47 import com.android.settings.utils.AnnotationSpan; 48 49 import org.junit.Before; 50 import org.junit.Rule; 51 import org.junit.Test; 52 import org.junit.runner.RunWith; 53 import org.mockito.Spy; 54 import org.mockito.junit.MockitoJUnit; 55 import org.mockito.junit.MockitoRule; 56 import org.robolectric.RobolectricTestRunner; 57 58 /** Tests for {@link MagnificationModePreferenceController}. */ 59 @RunWith(RobolectricTestRunner.class) 60 public class MagnificationModePreferenceControllerTest { 61 private static final String PREF_KEY = "screen_magnification_mode"; 62 private static final int MAGNIFICATION_MODE_DEFAULT = MagnificationMode.ALL; 63 64 @Rule 65 public MockitoRule mocks = MockitoJUnit.rule(); 66 67 private PreferenceScreen mScreen; 68 private Context mContext; 69 private MagnificationModePreferenceController mController; 70 private Preference mModePreference; 71 @Spy 72 private TestDialogHelper mDialogHelper = new TestDialogHelper(); 73 74 @Before setUp()75 public void setUp() { 76 mContext = ApplicationProvider.getApplicationContext(); 77 mContext.setTheme(androidx.appcompat.R.style.Theme_AppCompat); 78 final PreferenceManager preferenceManager = new PreferenceManager(mContext); 79 mScreen = preferenceManager.createPreferenceScreen(mContext); 80 mModePreference = new Preference(mContext); 81 mModePreference.setKey(PREF_KEY); 82 mScreen.addPreference(mModePreference); 83 MagnificationCapabilities.setCapabilities(mContext, MAGNIFICATION_MODE_DEFAULT); 84 mController = new MagnificationModePreferenceController(mContext, PREF_KEY); 85 showPreferenceOnTheScreen(null); 86 } 87 88 @Test clickPreference_settingsModeIsDefault_checkedModeInDialogIsDefault()89 public void clickPreference_settingsModeIsDefault_checkedModeInDialogIsDefault() { 90 mModePreference.getOnPreferenceClickListener().onPreferenceClick(mModePreference); 91 92 assertThat(getCheckedModeFromDialog()).isEqualTo(MAGNIFICATION_MODE_DEFAULT); 93 } 94 95 @Test choseModeIsDifferentFromInSettings_checkedModeInDialogIsExpected()96 public void choseModeIsDifferentFromInSettings_checkedModeInDialogIsExpected() { 97 mModePreference.getOnPreferenceClickListener().onPreferenceClick(mModePreference); 98 99 performItemClickWith(MagnificationMode.WINDOW); 100 101 assertThat(getCheckedModeFromDialog()).isEqualTo(MagnificationMode.WINDOW); 102 } 103 104 @Test dialogIsReCreated_settingsModeIsAllAndChoseWindowMode_checkedModeIsWindow()105 public void dialogIsReCreated_settingsModeIsAllAndChoseWindowMode_checkedModeIsWindow() { 106 mModePreference.getOnPreferenceClickListener().onPreferenceClick(mModePreference); 107 performItemClickWith(MagnificationMode.WINDOW); 108 109 reshowPreferenceOnTheScreen(); 110 mDialogHelper.showDialog(MagnificationModePreferenceController.DIALOG_MAGNIFICATION_MODE); 111 112 assertThat(getCheckedModeFromDialog()).isEqualTo( 113 MagnificationMode.WINDOW); 114 } 115 116 @Test chooseFullscreenMode_tripleTapEnabled_notShowTripleTapWarningDialog()117 public void chooseFullscreenMode_tripleTapEnabled_notShowTripleTapWarningDialog() { 118 enableTripleTap(); 119 mModePreference.getOnPreferenceClickListener().onPreferenceClick(mModePreference); 120 121 performItemClickWith(MagnificationMode.FULLSCREEN); 122 mController.onMagnificationModeDialogPositiveButtonClicked(mDialogHelper.getDialog(), 123 DialogInterface.BUTTON_POSITIVE); 124 125 verify(mDialogHelper, never()).showDialog( 126 MagnificationModePreferenceController.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING); 127 } 128 129 @Test chooseWindowMode_tripleTapEnabled_showTripleTapWarningDialog()130 public void chooseWindowMode_tripleTapEnabled_showTripleTapWarningDialog() { 131 enableTripleTap(); 132 mModePreference.getOnPreferenceClickListener().onPreferenceClick(mModePreference); 133 134 performItemClickWith(MagnificationMode.WINDOW); 135 mController.onMagnificationModeDialogPositiveButtonClicked(mDialogHelper.getDialog(), 136 DialogInterface.BUTTON_POSITIVE); 137 138 verify(mDialogHelper).showDialog( 139 MagnificationModePreferenceController.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING); 140 } 141 142 @Test chooseAllMode_tripleTapEnabled_showTripleTapWarningDialog()143 public void chooseAllMode_tripleTapEnabled_showTripleTapWarningDialog() { 144 enableTripleTap(); 145 mModePreference.getOnPreferenceClickListener().onPreferenceClick(mModePreference); 146 147 performItemClickWith(MagnificationMode.ALL); 148 mController.onMagnificationModeDialogPositiveButtonClicked(mDialogHelper.getDialog(), 149 DialogInterface.BUTTON_POSITIVE); 150 151 verify(mDialogHelper).showDialog( 152 MagnificationModePreferenceController.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING); 153 } 154 155 @Test onTripleTapWarningDialogNegativeButtonClicked_showModeDialog()156 public void onTripleTapWarningDialogNegativeButtonClicked_showModeDialog() { 157 mDialogHelper.showDialog( 158 MagnificationModePreferenceController.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING); 159 160 mController.onMagnificationTripleTapWarningDialogNegativeButtonClicked( 161 mDialogHelper.getDialog(), DialogInterface.BUTTON_NEGATIVE); 162 163 verify(mDialogHelper).showDialog( 164 MagnificationModePreferenceController.DIALOG_MAGNIFICATION_MODE); 165 } 166 167 @Test onTripleTapWarningDialogPositiveButtonClicked_chooseAllMode_returnAllSummary()168 public void onTripleTapWarningDialogPositiveButtonClicked_chooseAllMode_returnAllSummary() { 169 enableTripleTap(); 170 mModePreference.getOnPreferenceClickListener().onPreferenceClick(mModePreference); 171 performItemClickWith(MagnificationMode.ALL); 172 mController.onMagnificationModeDialogPositiveButtonClicked(mDialogHelper.getDialog(), 173 DialogInterface.BUTTON_POSITIVE); 174 175 mController.onMagnificationTripleTapWarningDialogPositiveButtonClicked( 176 mDialogHelper.getDialog(), DialogInterface.BUTTON_POSITIVE); 177 178 final String allSummary = mContext.getString( 179 R.string.accessibility_magnification_area_settings_all_summary); 180 assertThat(TextUtils.equals(mController.getSummary(), allSummary)).isTrue(); 181 } 182 183 @Test checkSpansInTripleTapWarningDialog_existAnnotationSpan()184 public void checkSpansInTripleTapWarningDialog_existAnnotationSpan() { 185 mDialogHelper.showDialog( 186 MagnificationModePreferenceController.DIALOG_MAGNIFICATION_TRIPLE_TAP_WARNING); 187 final View contentView = mDialogHelper.getDialog().findViewById(android.R.id.content); 188 final TextView messageView = contentView.findViewById(R.id.message); 189 final CharSequence textInTripleTapWarningDialog = messageView.getText(); 190 191 final AnnotationSpan[] annotationSpans = 192 ((SpannableString) textInTripleTapWarningDialog).getSpans(/*queryStart= */ 0, 193 textInTripleTapWarningDialog.length(), AnnotationSpan.class); 194 195 assertThat(annotationSpans[0]).isNotNull(); 196 } 197 198 @Test getSummary_saveWindowScreen_shouldReturnWindowScreenSummary()199 public void getSummary_saveWindowScreen_shouldReturnWindowScreenSummary() { 200 MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.WINDOW); 201 202 final String windowSummary = mContext.getString( 203 R.string.accessibility_magnification_area_settings_window_screen_summary); 204 assertThat(TextUtils.equals(mController.getSummary(), windowSummary)).isTrue(); 205 } 206 207 @Test getSummary_saveAll_shouldReturnAllSummary()208 public void getSummary_saveAll_shouldReturnAllSummary() { 209 MagnificationCapabilities.setCapabilities(mContext, MagnificationMode.ALL); 210 211 final String allSummary = mContext.getString( 212 R.string.accessibility_magnification_area_settings_all_summary); 213 assertThat(TextUtils.equals(mController.getSummary(), allSummary)).isTrue(); 214 } 215 getCheckedModeFromDialog()216 private int getCheckedModeFromDialog() { 217 final ListView listView = mController.mMagnificationModesListView; 218 assertThat(listView).isNotNull(); 219 220 final int checkedPosition = listView.getCheckedItemPosition(); 221 final MagnificationModeInfo modeInfo = 222 (MagnificationModeInfo) listView.getAdapter().getItem(checkedPosition); 223 return modeInfo.mMagnificationMode; 224 } 225 performItemClickWith(@agnificationMode int mode)226 private void performItemClickWith(@MagnificationMode int mode) { 227 final ListView listView = mController.mMagnificationModesListView; 228 assertThat(listView).isNotNull(); 229 230 int modeIndex = AdapterView.NO_ID; 231 // Index 0 is header. 232 for (int i = 1; i < listView.getAdapter().getCount(); i++) { 233 final MagnificationModeInfo modeInfo = 234 (MagnificationModeInfo) listView.getAdapter().getItem(i); 235 if (modeInfo.mMagnificationMode == mode) { 236 modeIndex = i; 237 break; 238 } 239 } 240 if (modeIndex == AdapterView.NO_ID) { 241 throw new RuntimeException("The mode is not in the list."); 242 } 243 244 listView.performItemClick(listView.getChildAt(modeIndex), modeIndex, modeIndex); 245 } 246 enableTripleTap()247 private void enableTripleTap() { 248 Settings.Secure.putInt(mContext.getContentResolver(), 249 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, ON); 250 } 251 reshowPreferenceOnTheScreen()252 private void reshowPreferenceOnTheScreen() { 253 final Bundle bundle = new Bundle(); 254 mController.onSaveInstanceState(bundle); 255 showPreferenceOnTheScreen(bundle); 256 } 257 showPreferenceOnTheScreen(Bundle savedInstanceState)258 private void showPreferenceOnTheScreen(Bundle savedInstanceState) { 259 mController.setDialogHelper(mDialogHelper); 260 mController.onCreate(savedInstanceState); 261 mController.displayPreference(mScreen); 262 } 263 264 private static class TestDialogHelper implements DialogCreatable, 265 MagnificationModePreferenceController.DialogHelper { 266 private DialogCreatable mDialogDelegate; 267 private Dialog mDialog; 268 269 @Override showDialog(int dialogId)270 public void showDialog(int dialogId) { 271 mDialog = onCreateDialog(dialogId); 272 } 273 274 @Override setDialogDelegate(DialogCreatable delegate)275 public void setDialogDelegate(DialogCreatable delegate) { 276 mDialogDelegate = delegate; 277 } 278 279 @Override onCreateDialog(int dialogId)280 public Dialog onCreateDialog(int dialogId) { 281 return mDialogDelegate.onCreateDialog(dialogId); 282 } 283 284 @Override getDialogMetricsCategory(int dialogId)285 public int getDialogMetricsCategory(int dialogId) { 286 return mDialogDelegate.getDialogMetricsCategory(dialogId); 287 } 288 getDialog()289 public Dialog getDialog() { 290 return mDialog; 291 } 292 } 293 } 294