1 /* 2 * Copyright (C) 2020 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.AccessibilityUtil.UserShortcutType; 22 import static com.android.settings.accessibility.MagnificationCapabilities.MagnificationMode; 23 import static com.android.settings.accessibility.ToggleFeaturePreferenceFragment.KEY_SAVED_USER_SHORTCUT_TYPE; 24 25 import static com.google.common.truth.Truth.assertThat; 26 27 import static org.junit.Assert.assertTrue; 28 import static org.mockito.ArgumentMatchers.anyInt; 29 import static org.mockito.Mockito.RETURNS_DEEP_STUBS; 30 import static org.mockito.Mockito.mock; 31 import static org.mockito.Mockito.spy; 32 import static org.mockito.Mockito.verify; 33 import static org.mockito.Mockito.verifyNoMoreInteractions; 34 import static org.mockito.Mockito.when; 35 36 import android.app.settings.SettingsEnums; 37 import android.content.ComponentName; 38 import android.content.Context; 39 import android.content.DialogInterface; 40 import android.content.pm.PackageManager; 41 import android.content.res.Resources; 42 import android.database.ContentObserver; 43 import android.icu.text.CaseMap; 44 import android.net.Uri; 45 import android.os.Bundle; 46 import android.os.UserHandle; 47 import android.platform.test.annotations.DisableFlags; 48 import android.platform.test.annotations.EnableFlags; 49 import android.platform.test.flag.junit.SetFlagsRule; 50 import android.provider.DeviceConfig; 51 import android.provider.Settings; 52 import android.view.accessibility.AccessibilityManager; 53 54 import androidx.appcompat.app.AlertDialog; 55 import androidx.preference.Preference; 56 import androidx.preference.TwoStatePreference; 57 import androidx.test.core.app.ApplicationProvider; 58 59 import com.android.server.accessibility.Flags; 60 import com.android.settings.DialogCreatable; 61 import com.android.settings.R; 62 import com.android.settings.SettingsActivity; 63 import com.android.settings.accessibility.AccessibilityDialogUtils.DialogType; 64 import com.android.settings.testutils.AccessibilityTestUtils; 65 import com.android.settings.testutils.shadow.ShadowDeviceConfig; 66 import com.android.settings.testutils.shadow.ShadowStorageManager; 67 import com.android.settings.testutils.shadow.ShadowUserManager; 68 import com.android.settingslib.core.lifecycle.LifecycleObserver; 69 70 import com.google.common.truth.Correspondence; 71 72 import org.junit.After; 73 import org.junit.Before; 74 import org.junit.Rule; 75 import org.junit.Test; 76 import org.junit.runner.RunWith; 77 import org.robolectric.RobolectricTestRunner; 78 import org.robolectric.Shadows; 79 import org.robolectric.annotation.Config; 80 import org.robolectric.shadows.ShadowContentResolver; 81 import org.robolectric.shadows.ShadowPackageManager; 82 import org.robolectric.shadows.ShadowSettings; 83 import org.robolectric.shadows.androidx.fragment.FragmentController; 84 import org.robolectric.util.ReflectionHelpers; 85 86 import java.util.Collection; 87 import java.util.List; 88 import java.util.Locale; 89 import java.util.Set; 90 91 /** Tests for {@link ToggleScreenMagnificationPreferenceFragment}. */ 92 @RunWith(RobolectricTestRunner.class) 93 @Config(shadows = { 94 ShadowUserManager.class, 95 ShadowStorageManager.class, 96 ShadowSettings.ShadowSecure.class, 97 ShadowDeviceConfig.class, 98 }) 99 public class ToggleScreenMagnificationPreferenceFragmentTest { 100 101 @Rule 102 public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); 103 104 private static final String PLACEHOLDER_PACKAGE_NAME = "com.mock.example"; 105 private static final String PLACEHOLDER_CLASS_NAME = 106 PLACEHOLDER_PACKAGE_NAME + ".mock_a11y_service"; 107 private static final ComponentName PLACEHOLDER_COMPONENT_NAME = new ComponentName( 108 PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_CLASS_NAME); 109 private static final String PLACEHOLDER_DIALOG_TITLE = "title"; 110 111 private static final String SOFTWARE_SHORTCUT_KEY = 112 Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS; 113 private static final String HARDWARE_SHORTCUT_KEY = 114 Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE; 115 private static final String TRIPLETAP_SHORTCUT_KEY = 116 Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED; 117 private static final String TWO_FINGER_TRIPLE_TAP_SHORTCUT_KEY = 118 Settings.Secure.ACCESSIBILITY_MAGNIFICATION_TWO_FINGER_TRIPLE_TAP_ENABLED; 119 120 private static final String MAGNIFICATION_CONTROLLER_NAME = 121 "com.android.server.accessibility.MagnificationController"; 122 123 private static final String KEY_FOLLOW_TYPING = 124 Settings.Secure.ACCESSIBILITY_MAGNIFICATION_FOLLOW_TYPING_ENABLED; 125 private static final String KEY_SINGLE_FINGER_PANNING = 126 Settings.Secure.ACCESSIBILITY_SINGLE_FINGER_PANNING_ENABLED; 127 private static final String KEY_ALWAYS_ON = 128 Settings.Secure.ACCESSIBILITY_MAGNIFICATION_ALWAYS_ON_ENABLED; 129 private static final String KEY_JOYSTICK = 130 Settings.Secure.ACCESSIBILITY_MAGNIFICATION_JOYSTICK_ENABLED; 131 132 private FragmentController<ToggleScreenMagnificationPreferenceFragment> mFragController; 133 private Context mContext; 134 private AccessibilityManager mAccessibilityManager; 135 private Resources mSpyResources; 136 private ShadowPackageManager mShadowPackageManager; 137 138 @Before setUpTestFragment()139 public void setUpTestFragment() { 140 141 mContext = spy(ApplicationProvider.getApplicationContext()); 142 mAccessibilityManager = AccessibilityTestUtils.setupMockAccessibilityManager(mContext); 143 144 // Set up the fragment that support window magnification feature 145 mSpyResources = spy(mContext.getResources()); 146 mShadowPackageManager = Shadows.shadowOf(mContext.getPackageManager()); 147 Context spyContext = spy(mContext); 148 when(spyContext.getResources()).thenReturn(mSpyResources); 149 150 setWindowMagnificationSupported( 151 /* magnificationAreaSupported= */ true, 152 /* windowMagnificationSupported= */ true); 153 154 TestToggleScreenMagnificationPreferenceFragment fragment = 155 new TestToggleScreenMagnificationPreferenceFragment(); 156 fragment.setArguments(new Bundle()); 157 fragment.setContext(spyContext); 158 159 mFragController = FragmentController.of(fragment, SettingsActivity.class); 160 } 161 162 @After tearDown()163 public void tearDown() { 164 ShadowDeviceConfig.reset(); 165 } 166 167 @Test onResume_defaultStateForMagnificationMode_preferenceShouldReturnFullScreen()168 public void onResume_defaultStateForMagnificationMode_preferenceShouldReturnFullScreen() { 169 mFragController.create(R.id.main_content, /* bundle= */ null).start().resume(); 170 171 // Default is MagnificationMode.FULLSCREEN 172 final String expected = 173 MagnificationCapabilities.getSummary(mContext, MagnificationMode.FULLSCREEN); 174 175 final Preference preference = mFragController.get().findPreference( 176 MagnificationModePreferenceController.PREF_KEY); 177 assertThat(preference).isNotNull(); 178 assertThat(preference.getSummary()).isEqualTo(expected); 179 } 180 181 @Test onResume_setMagnificationModeToAll_preferenceShouldReturnAll()182 public void onResume_setMagnificationModeToAll_preferenceShouldReturnAll() { 183 setKeyMagnificationMode(MagnificationMode.ALL); 184 185 mFragController.create(R.id.main_content, /* bundle= */ null).start().resume(); 186 187 final String expected = 188 MagnificationCapabilities.getSummary(mContext, MagnificationMode.ALL); 189 190 final Preference preference = mFragController.get().findPreference( 191 MagnificationModePreferenceController.PREF_KEY); 192 assertThat(preference).isNotNull(); 193 assertThat(preference.getSummary()).isEqualTo(expected); 194 } 195 196 @Test onResume_defaultStateForFollowingTyping_switchPreferenceShouldReturnTrue()197 public void onResume_defaultStateForFollowingTyping_switchPreferenceShouldReturnTrue() { 198 setKeyFollowTypingEnabled(true); 199 200 mFragController.create(R.id.main_content, /* bundle= */ null).start().resume(); 201 202 final TwoStatePreference switchPreference = mFragController.get().findPreference( 203 MagnificationFollowTypingPreferenceController.PREF_KEY); 204 assertThat(switchPreference).isNotNull(); 205 assertThat(switchPreference.isChecked()).isTrue(); 206 } 207 208 @Test onResume_disableFollowingTyping_switchPreferenceShouldReturnFalse()209 public void onResume_disableFollowingTyping_switchPreferenceShouldReturnFalse() { 210 setKeyFollowTypingEnabled(false); 211 212 mFragController.create(R.id.main_content, /* bundle= */ null).start().resume(); 213 214 final TwoStatePreference switchPreference = mFragController.get().findPreference( 215 MagnificationFollowTypingPreferenceController.PREF_KEY); 216 assertThat(switchPreference).isNotNull(); 217 assertThat(switchPreference.isChecked()).isFalse(); 218 } 219 220 @Test 221 @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE) onResume_defaultStateForOneFingerPan_switchPreferenceShouldReturnFalse()222 public void onResume_defaultStateForOneFingerPan_switchPreferenceShouldReturnFalse() { 223 mFragController.create(R.id.main_content, /* bundle= */ null).start().resume(); 224 225 final TwoStatePreference switchPreference = mFragController.get().findPreference( 226 MagnificationOneFingerPanningPreferenceController.PREF_KEY); 227 assertThat(switchPreference).isNotNull(); 228 assertThat(switchPreference.isChecked()).isFalse(); 229 } 230 231 @Test 232 @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE) onResume_enableOneFingerPan_switchPreferenceShouldReturnTrue()233 public void onResume_enableOneFingerPan_switchPreferenceShouldReturnTrue() { 234 setKeyOneFingerPanEnabled(true); 235 236 mFragController.create(R.id.main_content, /* bundle= */ null).start().resume(); 237 238 final TwoStatePreference switchPreference = mFragController.get().findPreference( 239 MagnificationOneFingerPanningPreferenceController.PREF_KEY); 240 assertThat(switchPreference).isNotNull(); 241 assertThat(switchPreference.isChecked()).isTrue(); 242 } 243 244 @Test 245 @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE) onResume_disableOneFingerPan_switchPreferenceShouldReturnFalse()246 public void onResume_disableOneFingerPan_switchPreferenceShouldReturnFalse() { 247 setKeyOneFingerPanEnabled(false); 248 249 mFragController.create(R.id.main_content, /* bundle= */ null).start().resume(); 250 251 final TwoStatePreference switchPreference = mFragController.get().findPreference( 252 MagnificationOneFingerPanningPreferenceController.PREF_KEY); 253 assertThat(switchPreference).isNotNull(); 254 assertThat(switchPreference.isChecked()).isFalse(); 255 } 256 257 @Test onResume_defaultStateForAlwaysOn_switchPreferenceShouldReturnTrue()258 public void onResume_defaultStateForAlwaysOn_switchPreferenceShouldReturnTrue() { 259 setAlwaysOnSupported(true); 260 261 mFragController.create(R.id.main_content, /* bundle= */ null).start().resume(); 262 263 final TwoStatePreference switchPreference = mFragController.get().findPreference( 264 MagnificationAlwaysOnPreferenceController.PREF_KEY); 265 assertThat(switchPreference).isNotNull(); 266 assertThat(switchPreference.isChecked()).isTrue(); 267 } 268 269 @Test onResume_enableAlwaysOn_switchPreferenceShouldReturnTrue()270 public void onResume_enableAlwaysOn_switchPreferenceShouldReturnTrue() { 271 setAlwaysOnSupported(true); 272 setKeyAlwaysOnEnabled(true); 273 274 mFragController.create(R.id.main_content, /* bundle= */ null).start().resume(); 275 276 final TwoStatePreference switchPreference = mFragController.get().findPreference( 277 MagnificationAlwaysOnPreferenceController.PREF_KEY); 278 assertThat(switchPreference).isNotNull(); 279 assertThat(switchPreference.isChecked()).isTrue(); 280 } 281 282 @Test onResume_disableAlwaysOn_switchPreferenceShouldReturnFalse()283 public void onResume_disableAlwaysOn_switchPreferenceShouldReturnFalse() { 284 setAlwaysOnSupported(true); 285 setKeyAlwaysOnEnabled(false); 286 287 mFragController.create(R.id.main_content, /* bundle= */ null).start().resume(); 288 289 final TwoStatePreference switchPreference = mFragController.get().findPreference( 290 MagnificationAlwaysOnPreferenceController.PREF_KEY); 291 assertThat(switchPreference).isNotNull(); 292 assertThat(switchPreference.isChecked()).isFalse(); 293 } 294 295 @Test onResume_defaultStateForJoystick_switchPreferenceShouldReturnFalse()296 public void onResume_defaultStateForJoystick_switchPreferenceShouldReturnFalse() { 297 setJoystickSupported(true); 298 299 mFragController.create(R.id.main_content, /* bundle= */ null).start().resume(); 300 301 final TwoStatePreference switchPreference = mFragController.get().findPreference( 302 MagnificationJoystickPreferenceController.PREF_KEY); 303 assertThat(switchPreference).isNotNull(); 304 assertThat(switchPreference.isChecked()).isFalse(); 305 } 306 307 @Test onResume_enableJoystick_switchPreferenceShouldReturnTrue()308 public void onResume_enableJoystick_switchPreferenceShouldReturnTrue() { 309 setJoystickSupported(true); 310 setKeyJoystickEnabled(true); 311 312 mFragController.create(R.id.main_content, /* bundle= */ null).start().resume(); 313 314 final TwoStatePreference switchPreference = mFragController.get().findPreference( 315 MagnificationJoystickPreferenceController.PREF_KEY); 316 assertThat(switchPreference).isNotNull(); 317 assertThat(switchPreference.isChecked()).isTrue(); 318 } 319 320 @Test onResume_disableJoystick_switchPreferenceShouldReturnFalse()321 public void onResume_disableJoystick_switchPreferenceShouldReturnFalse() { 322 setJoystickSupported(true); 323 setKeyJoystickEnabled(false); 324 325 mFragController.create(R.id.main_content, /* bundle= */ null).start().resume(); 326 327 final TwoStatePreference switchPreference = mFragController.get().findPreference( 328 MagnificationJoystickPreferenceController.PREF_KEY); 329 assertThat(switchPreference).isNotNull(); 330 assertThat(switchPreference.isChecked()).isFalse(); 331 } 332 333 @Test 334 @EnableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) onResume_flagEnabled_haveRegisterToSpecificUris()335 public void onResume_flagEnabled_haveRegisterToSpecificUris() { 336 ShadowContentResolver shadowContentResolver = Shadows.shadowOf( 337 mContext.getContentResolver()); 338 Uri[] observedUri = new Uri[]{ 339 Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS), 340 Settings.Secure.getUriFor( 341 Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE), 342 Settings.Secure.getUriFor( 343 Settings.Secure.ACCESSIBILITY_QS_TARGETS), 344 Settings.Secure.getUriFor( 345 Settings.Secure.ACCESSIBILITY_MAGNIFICATION_FOLLOW_TYPING_ENABLED), 346 Settings.Secure.getUriFor( 347 Settings.Secure.ACCESSIBILITY_MAGNIFICATION_ALWAYS_ON_ENABLED) 348 }; 349 for (Uri uri : observedUri) { 350 // verify no observer registered before launching the fragment 351 assertThat(shadowContentResolver.getContentObservers(uri)).isEmpty(); 352 } 353 354 mFragController.create(R.id.main_content, /* bundle= */ null).start().resume(); 355 356 for (Uri uri : observedUri) { 357 Collection<ContentObserver> observers = shadowContentResolver.getContentObservers(uri); 358 assertThat(observers.size()).isEqualTo(1); 359 assertThat(observers.stream().findFirst().get()).isInstanceOf( 360 AccessibilitySettingsContentObserver.class); 361 } 362 } 363 364 @Test 365 @DisableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) onResume_flagDisabled_haveRegisterToSpecificUris()366 public void onResume_flagDisabled_haveRegisterToSpecificUris() { 367 ShadowContentResolver shadowContentResolver = Shadows.shadowOf( 368 mContext.getContentResolver()); 369 Uri[] observedUri = new Uri[]{ 370 Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS), 371 Settings.Secure.getUriFor( 372 Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE), 373 Settings.Secure.getUriFor( 374 Settings.Secure.ACCESSIBILITY_MAGNIFICATION_FOLLOW_TYPING_ENABLED), 375 Settings.Secure.getUriFor( 376 Settings.Secure.ACCESSIBILITY_MAGNIFICATION_ALWAYS_ON_ENABLED) 377 }; 378 for (Uri uri : observedUri) { 379 // verify no observer registered before launching the fragment 380 assertThat(shadowContentResolver.getContentObservers(uri)).isEmpty(); 381 } 382 383 mFragController.create(R.id.main_content, /* bundle= */ null).start().resume(); 384 385 for (Uri uri : observedUri) { 386 Collection<ContentObserver> observers = shadowContentResolver.getContentObservers(uri); 387 assertThat(observers.size()).isEqualTo(1); 388 assertThat(observers.stream().findFirst().get()).isInstanceOf( 389 AccessibilitySettingsContentObserver.class); 390 } 391 assertThat(shadowContentResolver.getContentObservers( 392 Settings.Secure.getUriFor( 393 Settings.Secure.ACCESSIBILITY_QS_TARGETS))).hasSize(0); 394 } 395 396 @Test hasValueInSettings_putValue_hasValue()397 public void hasValueInSettings_putValue_hasValue() { 398 setMagnificationTripleTapEnabled(/* enabled= */ true); 399 400 assertThat(ToggleScreenMagnificationPreferenceFragment.hasMagnificationValuesInSettings( 401 mContext, UserShortcutType.TRIPLETAP)).isTrue(); 402 } 403 404 @Test 405 @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE) hasMagnificationValuesInSettings_twoFingerTripleTapIsOn_isTrue()406 public void hasMagnificationValuesInSettings_twoFingerTripleTapIsOn_isTrue() { 407 Settings.Secure.putInt( 408 mContext.getContentResolver(), TWO_FINGER_TRIPLE_TAP_SHORTCUT_KEY, ON); 409 410 assertThat(ToggleScreenMagnificationPreferenceFragment.hasMagnificationValuesInSettings( 411 mContext, UserShortcutType.TWOFINGER_DOUBLETAP)).isTrue(); 412 } 413 414 @Test 415 @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE) hasMagnificationValuesInSettings_twoFingerTripleTapIsOff_isFalse()416 public void hasMagnificationValuesInSettings_twoFingerTripleTapIsOff_isFalse() { 417 Settings.Secure.putInt( 418 mContext.getContentResolver(), TWO_FINGER_TRIPLE_TAP_SHORTCUT_KEY, OFF); 419 420 assertThat(ToggleScreenMagnificationPreferenceFragment.hasMagnificationValuesInSettings( 421 mContext, UserShortcutType.TWOFINGER_DOUBLETAP)).isFalse(); 422 } 423 424 @Test 425 @DisableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) optInAllValuesToSettings_optInValue_haveMatchString()426 public void optInAllValuesToSettings_optInValue_haveMatchString() { 427 int shortcutTypes = UserShortcutType.SOFTWARE | UserShortcutType.TRIPLETAP; 428 429 ToggleScreenMagnificationPreferenceFragment.optInAllMagnificationValuesToSettings(mContext, 430 shortcutTypes); 431 432 assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEqualTo( 433 MAGNIFICATION_CONTROLLER_NAME); 434 assertThat(getMagnificationTripleTapStatus()).isTrue(); 435 } 436 437 @Test 438 @EnableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) optInAllValuesToSettings_optInValue_callA11yManager()439 public void optInAllValuesToSettings_optInValue_callA11yManager() { 440 int shortcutTypes = 441 UserShortcutType.SOFTWARE | UserShortcutType.TRIPLETAP | UserShortcutType.HARDWARE 442 | UserShortcutType.QUICK_SETTINGS; 443 Set<String> shortcutTargets = Set.of(MAGNIFICATION_CONTROLLER_NAME); 444 445 ToggleScreenMagnificationPreferenceFragment.optInAllMagnificationValuesToSettings(mContext, 446 shortcutTypes); 447 448 verify(mAccessibilityManager).enableShortcutsForTargets( 449 /* enable= */ true, UserShortcutType.SOFTWARE, 450 shortcutTargets, UserHandle.myUserId()); 451 verify(mAccessibilityManager).enableShortcutsForTargets( 452 /* enable= */ true, UserShortcutType.HARDWARE, 453 shortcutTargets, UserHandle.myUserId()); 454 verify(mAccessibilityManager).enableShortcutsForTargets( 455 /* enable= */ true, UserShortcutType.QUICK_SETTINGS, 456 shortcutTargets, UserHandle.myUserId()); 457 verify(mAccessibilityManager).enableShortcutsForTargets( 458 /* enable= */ true, UserShortcutType.TRIPLETAP, 459 shortcutTargets, UserHandle.myUserId()); 460 verifyNoMoreInteractions(mAccessibilityManager); 461 } 462 463 @Test 464 @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE) 465 @DisableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) optInAllValuesToSettings_twoFingerTripleTap_haveMatchString()466 public void optInAllValuesToSettings_twoFingerTripleTap_haveMatchString() { 467 int shortcutTypes = UserShortcutType.TWOFINGER_DOUBLETAP; 468 469 ToggleScreenMagnificationPreferenceFragment.optInAllMagnificationValuesToSettings(mContext, 470 shortcutTypes); 471 472 assertThat(Settings.Secure.getInt(mContext.getContentResolver(), 473 TWO_FINGER_TRIPLE_TAP_SHORTCUT_KEY, OFF)).isEqualTo(ON); 474 } 475 476 @Test 477 @DisableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) optInAllValuesToSettings_existOtherValue_optInValue_haveMatchString()478 public void optInAllValuesToSettings_existOtherValue_optInValue_haveMatchString() { 479 putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, PLACEHOLDER_COMPONENT_NAME.flattenToString()); 480 481 ToggleScreenMagnificationPreferenceFragment.optInAllMagnificationValuesToSettings(mContext, 482 UserShortcutType.SOFTWARE); 483 484 assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEqualTo( 485 PLACEHOLDER_COMPONENT_NAME.flattenToString() + ":" + MAGNIFICATION_CONTROLLER_NAME); 486 } 487 488 @Test 489 @DisableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) optInAllValuesToSettings_software_sizeValueIsNull_putLargeSizeValue()490 public void optInAllValuesToSettings_software_sizeValueIsNull_putLargeSizeValue() { 491 ShadowSettings.ShadowSecure.reset(); 492 493 ToggleScreenMagnificationPreferenceFragment.optInAllMagnificationValuesToSettings(mContext, 494 UserShortcutType.SOFTWARE); 495 496 assertThat(Settings.Secure.getInt(mContext.getContentResolver(), 497 Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE, 498 FloatingMenuSizePreferenceController.Size.UNKNOWN)).isEqualTo( 499 FloatingMenuSizePreferenceController.Size.LARGE); 500 } 501 502 @Test optInAllValuesToSettings_software_sizeValueIsNotNull_sizeValueIsNotChanged()503 public void optInAllValuesToSettings_software_sizeValueIsNotNull_sizeValueIsNotChanged() { 504 for (int size : new int[] {FloatingMenuSizePreferenceController.Size.LARGE, 505 FloatingMenuSizePreferenceController.Size.SMALL}) { 506 Settings.Secure.putInt(mContext.getContentResolver(), 507 Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE, size); 508 509 ToggleScreenMagnificationPreferenceFragment.optInAllMagnificationValuesToSettings( 510 mContext, 511 UserShortcutType.SOFTWARE); 512 513 assertThat(Settings.Secure.getInt(mContext.getContentResolver(), 514 Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE, 515 FloatingMenuSizePreferenceController.Size.UNKNOWN)).isEqualTo( 516 size); 517 } 518 } 519 520 @Test optInAllValuesToSettings_hardware_sizeValueIsNotChanged()521 public void optInAllValuesToSettings_hardware_sizeValueIsNotChanged() { 522 for (int size : new int[] {FloatingMenuSizePreferenceController.Size.UNKNOWN, 523 FloatingMenuSizePreferenceController.Size.LARGE, 524 FloatingMenuSizePreferenceController.Size.SMALL}) { 525 Settings.Secure.putInt(mContext.getContentResolver(), 526 Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE, size); 527 528 ToggleScreenMagnificationPreferenceFragment.optInAllMagnificationValuesToSettings( 529 mContext, 530 UserShortcutType.HARDWARE); 531 532 assertThat(Settings.Secure.getInt(mContext.getContentResolver(), 533 Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE, size + 1)).isEqualTo( 534 size); 535 } 536 } 537 538 @Test optInAllValuesToSettings_tripletap_sizeValueIsNotChanged()539 public void optInAllValuesToSettings_tripletap_sizeValueIsNotChanged() { 540 for (int size : new int[] {FloatingMenuSizePreferenceController.Size.UNKNOWN, 541 FloatingMenuSizePreferenceController.Size.LARGE, 542 FloatingMenuSizePreferenceController.Size.SMALL}) { 543 Settings.Secure.putInt(mContext.getContentResolver(), 544 Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE, size); 545 546 ToggleScreenMagnificationPreferenceFragment.optInAllMagnificationValuesToSettings( 547 mContext, 548 UserShortcutType.TRIPLETAP); 549 550 assertThat(Settings.Secure.getInt(mContext.getContentResolver(), 551 Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE, size + 1)).isEqualTo( 552 size); 553 } 554 } 555 556 @Test 557 @DisableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) optOutAllValuesToSettings_optOutValue_emptyString()558 public void optOutAllValuesToSettings_optOutValue_emptyString() { 559 putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, MAGNIFICATION_CONTROLLER_NAME); 560 putStringIntoSettings(HARDWARE_SHORTCUT_KEY, MAGNIFICATION_CONTROLLER_NAME); 561 setMagnificationTripleTapEnabled(/* enabled= */ true); 562 int shortcutTypes = 563 UserShortcutType.SOFTWARE | UserShortcutType.HARDWARE | UserShortcutType.TRIPLETAP; 564 565 ToggleScreenMagnificationPreferenceFragment.optOutAllMagnificationValuesFromSettings( 566 mContext, shortcutTypes); 567 568 assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEmpty(); 569 assertThat(getStringFromSettings(HARDWARE_SHORTCUT_KEY)).isEmpty(); 570 assertThat(getMagnificationTripleTapStatus()).isFalse(); 571 } 572 573 @Test 574 @EnableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) optOutAllValuesToSettings_optOutValue_callA11yManager()575 public void optOutAllValuesToSettings_optOutValue_callA11yManager() { 576 Set<String> shortcutTargets = Set.of(MAGNIFICATION_CONTROLLER_NAME); 577 putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, MAGNIFICATION_CONTROLLER_NAME); 578 putStringIntoSettings(HARDWARE_SHORTCUT_KEY, MAGNIFICATION_CONTROLLER_NAME); 579 setMagnificationTripleTapEnabled(/* enabled= */ true); 580 int shortcutTypes = 581 UserShortcutType.SOFTWARE | UserShortcutType.HARDWARE | UserShortcutType.TRIPLETAP; 582 583 ToggleScreenMagnificationPreferenceFragment.optOutAllMagnificationValuesFromSettings( 584 mContext, shortcutTypes); 585 586 verify(mAccessibilityManager).enableShortcutsForTargets( 587 /* enable= */ false, UserShortcutType.SOFTWARE, 588 shortcutTargets, UserHandle.myUserId()); 589 verify(mAccessibilityManager).enableShortcutsForTargets( 590 /* enable= */ false, UserShortcutType.HARDWARE, 591 shortcutTargets, UserHandle.myUserId()); 592 verify(mAccessibilityManager).enableShortcutsForTargets( 593 /* enable= */ false, UserShortcutType.TRIPLETAP, 594 shortcutTargets, UserHandle.myUserId()); 595 verifyNoMoreInteractions(mAccessibilityManager); 596 } 597 598 @Test 599 @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE) 600 @DisableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) optOutAllValuesToSettings_twoFingerTripleTap_settingsValueIsOff()601 public void optOutAllValuesToSettings_twoFingerTripleTap_settingsValueIsOff() { 602 Settings.Secure.putInt(mContext.getContentResolver(), 603 TWO_FINGER_TRIPLE_TAP_SHORTCUT_KEY, ON); 604 605 ToggleScreenMagnificationPreferenceFragment.optOutAllMagnificationValuesFromSettings( 606 mContext, UserShortcutType.TWOFINGER_DOUBLETAP); 607 608 assertThat(Settings.Secure.getInt(mContext.getContentResolver(), 609 TWO_FINGER_TRIPLE_TAP_SHORTCUT_KEY, ON)).isEqualTo(OFF); 610 } 611 612 @Test 613 @DisableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) optOutValueFromSettings_existOtherValue_optOutValue_haveMatchString()614 public void optOutValueFromSettings_existOtherValue_optOutValue_haveMatchString() { 615 putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, 616 PLACEHOLDER_COMPONENT_NAME.flattenToString() + ":" + MAGNIFICATION_CONTROLLER_NAME); 617 putStringIntoSettings(HARDWARE_SHORTCUT_KEY, 618 PLACEHOLDER_COMPONENT_NAME.flattenToString() + ":" + MAGNIFICATION_CONTROLLER_NAME); 619 int shortcutTypes = UserShortcutType.SOFTWARE | UserShortcutType.HARDWARE; 620 621 ToggleScreenMagnificationPreferenceFragment.optOutAllMagnificationValuesFromSettings( 622 mContext, shortcutTypes); 623 624 assertThat(getStringFromSettings(SOFTWARE_SHORTCUT_KEY)).isEqualTo( 625 PLACEHOLDER_COMPONENT_NAME.flattenToString()); 626 assertThat(getStringFromSettings(HARDWARE_SHORTCUT_KEY)).isEqualTo( 627 PLACEHOLDER_COMPONENT_NAME.flattenToString()); 628 } 629 630 @Test updateShortcutPreferenceData_assignDefaultValueToVariable()631 public void updateShortcutPreferenceData_assignDefaultValueToVariable() { 632 mFragController.create(R.id.main_content, /* bundle= */ null).start().resume(); 633 634 mFragController.get().updateShortcutPreferenceData(); 635 636 final int expectedType = PreferredShortcuts.retrieveUserShortcutType(mContext, 637 MAGNIFICATION_CONTROLLER_NAME); 638 // Compare to default UserShortcutType 639 assertThat(expectedType).isEqualTo(UserShortcutType.SOFTWARE); 640 } 641 642 @Test updateShortcutPreferenceData_hasValueInSettings_assignToVariable()643 public void updateShortcutPreferenceData_hasValueInSettings_assignToVariable() { 644 putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, MAGNIFICATION_CONTROLLER_NAME); 645 setMagnificationTripleTapEnabled(/* enabled= */ true); 646 mFragController.create(R.id.main_content, /* bundle= */ null).start().resume(); 647 648 mFragController.get().updateShortcutPreferenceData(); 649 650 final int expectedType = PreferredShortcuts.retrieveUserShortcutType(mContext, 651 MAGNIFICATION_CONTROLLER_NAME); 652 assertThat(expectedType).isEqualTo(UserShortcutType.SOFTWARE | UserShortcutType.TRIPLETAP); 653 } 654 655 @Test updateShortcutPreferenceData_hasValueInSharedPreference_assignToVariable()656 public void updateShortcutPreferenceData_hasValueInSharedPreference_assignToVariable() { 657 final PreferredShortcut tripleTapShortcut = new PreferredShortcut( 658 MAGNIFICATION_CONTROLLER_NAME, UserShortcutType.TRIPLETAP); 659 putUserShortcutTypeIntoSharedPreference(mContext, tripleTapShortcut); 660 mFragController.create(R.id.main_content, /* bundle= */ null).start().resume(); 661 662 mFragController.get().updateShortcutPreferenceData(); 663 664 final int expectedType = PreferredShortcuts.retrieveUserShortcutType(mContext, 665 MAGNIFICATION_CONTROLLER_NAME); 666 assertThat(expectedType).isEqualTo(UserShortcutType.TRIPLETAP); 667 } 668 669 @Test 670 @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE) updateShortcutPreferenceData_hasTwoFingerTripleTapInSettings_assignToVariable()671 public void updateShortcutPreferenceData_hasTwoFingerTripleTapInSettings_assignToVariable() { 672 Settings.Secure.putInt( 673 mContext.getContentResolver(), TWO_FINGER_TRIPLE_TAP_SHORTCUT_KEY, ON); 674 mFragController.create(R.id.main_content, /* bundle= */ null).start().resume(); 675 676 mFragController.get().updateShortcutPreferenceData(); 677 678 final int expectedType = PreferredShortcuts.retrieveUserShortcutType(mContext, 679 MAGNIFICATION_CONTROLLER_NAME); 680 assertThat(expectedType).isEqualTo(UserShortcutType.TWOFINGER_DOUBLETAP); 681 } 682 683 @Test 684 @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE) updateShortcutPreferenceData_hasTwoFingerTripleTapInSharedPref_assignToVariable()685 public void updateShortcutPreferenceData_hasTwoFingerTripleTapInSharedPref_assignToVariable() { 686 final PreferredShortcut tripleTapShortcut = new PreferredShortcut( 687 MAGNIFICATION_CONTROLLER_NAME, UserShortcutType.TWOFINGER_DOUBLETAP); 688 putUserShortcutTypeIntoSharedPreference(mContext, tripleTapShortcut); 689 mFragController.create(R.id.main_content, /* bundle= */ null).start().resume(); 690 691 mFragController.get().updateShortcutPreferenceData(); 692 693 final int expectedType = PreferredShortcuts.retrieveUserShortcutType(mContext, 694 MAGNIFICATION_CONTROLLER_NAME); 695 assertThat(expectedType).isEqualTo(UserShortcutType.TWOFINGER_DOUBLETAP); 696 } 697 698 @Test setupMagnificationEditShortcutDialog_shortcutPreferenceOff_checkboxIsEmptyValue()699 public void setupMagnificationEditShortcutDialog_shortcutPreferenceOff_checkboxIsEmptyValue() { 700 ToggleScreenMagnificationPreferenceFragment fragment = 701 mFragController.create(R.id.main_content, /* bundle= */ 702 null).start().resume().get(); 703 fragment.mShortcutPreference = new ShortcutPreference(mContext, /* attrs= */ null); 704 705 fragment.mShortcutPreference.setChecked(false); 706 fragment.setupMagnificationEditShortcutDialog( 707 createEditShortcutDialog(fragment.getActivity())); 708 709 final int checkboxValue = fragment.getShortcutTypeCheckBoxValue(); 710 assertThat(checkboxValue).isEqualTo(UserShortcutType.EMPTY); 711 } 712 713 @Test setupMagnificationEditShortcutDialog_shortcutPreferenceOn_checkboxIsSavedValue()714 public void setupMagnificationEditShortcutDialog_shortcutPreferenceOn_checkboxIsSavedValue() { 715 ToggleScreenMagnificationPreferenceFragment fragment = 716 mFragController.create(R.id.main_content, /* bundle= */ 717 null).start().resume().get(); 718 final ShortcutPreference shortcutPreference = new ShortcutPreference(mContext, /* attrs= */ 719 null); 720 final PreferredShortcut tripletapShortcut = new PreferredShortcut( 721 MAGNIFICATION_CONTROLLER_NAME, UserShortcutType.TRIPLETAP); 722 fragment.mShortcutPreference = shortcutPreference; 723 724 PreferredShortcuts.saveUserShortcutType(mContext, tripletapShortcut); 725 fragment.mShortcutPreference.setChecked(true); 726 fragment.setupMagnificationEditShortcutDialog( 727 createEditShortcutDialog(fragment.getActivity())); 728 729 final int checkboxValue = fragment.getShortcutTypeCheckBoxValue(); 730 assertThat(checkboxValue).isEqualTo(UserShortcutType.TRIPLETAP); 731 } 732 733 @Test 734 @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE) setupMagnificationEditShortcutDialog_twoFingerTripleTapOn_checkboxIsSavedValue()735 public void setupMagnificationEditShortcutDialog_twoFingerTripleTapOn_checkboxIsSavedValue() { 736 ToggleScreenMagnificationPreferenceFragment fragment = 737 mFragController.create(R.id.main_content, /* bundle= */ 738 null).start().resume().get(); 739 final ShortcutPreference shortcutPreference = new ShortcutPreference(mContext, /* attrs= */ 740 null); 741 final PreferredShortcut twoFingerTripleTapShortcut = new PreferredShortcut( 742 MAGNIFICATION_CONTROLLER_NAME, UserShortcutType.TWOFINGER_DOUBLETAP); 743 fragment.mShortcutPreference = shortcutPreference; 744 745 PreferredShortcuts.saveUserShortcutType(mContext, twoFingerTripleTapShortcut); 746 fragment.mShortcutPreference.setChecked(true); 747 fragment.setupMagnificationEditShortcutDialog( 748 createEditShortcutDialog(fragment.getActivity())); 749 750 final int checkboxValue = fragment.getShortcutTypeCheckBoxValue(); 751 assertThat(checkboxValue).isEqualTo(UserShortcutType.TWOFINGER_DOUBLETAP); 752 } 753 754 @Test restoreValueFromSavedInstanceState_assignToVariable()755 public void restoreValueFromSavedInstanceState_assignToVariable() { 756 final Bundle fragmentState = createFragmentSavedInstanceState( 757 UserShortcutType.HARDWARE | UserShortcutType.TRIPLETAP); 758 ToggleScreenMagnificationPreferenceFragment fragment = mFragController.get(); 759 // Had to use reflection to pass the savedInstanceState when launching the fragment 760 ReflectionHelpers.setField(fragment, "mSavedFragmentState", fragmentState); 761 762 FragmentController.of(fragment, SettingsActivity.class).create( 763 R.id.main_content, /* bundle= */ null).start().resume().get(); 764 fragment.setupMagnificationEditShortcutDialog( 765 createEditShortcutDialog(fragment.getActivity())); 766 final int value = fragment.getShortcutTypeCheckBoxValue(); 767 fragment.saveNonEmptyUserShortcutType(value); 768 769 final int expectedType = PreferredShortcuts.retrieveUserShortcutType(mContext, 770 MAGNIFICATION_CONTROLLER_NAME); 771 assertThat(value).isEqualTo(6); 772 assertThat(expectedType).isEqualTo(UserShortcutType.HARDWARE | UserShortcutType.TRIPLETAP); 773 } 774 775 @Test 776 @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE) restoreValueFromSavedInstanceState_twoFingerTripleTap_assignToVariable()777 public void restoreValueFromSavedInstanceState_twoFingerTripleTap_assignToVariable() { 778 final Bundle fragmentState = 779 createFragmentSavedInstanceState(UserShortcutType.TWOFINGER_DOUBLETAP); 780 ToggleScreenMagnificationPreferenceFragment fragment = mFragController.get(); 781 // Had to use reflection to pass the savedInstanceState when launching the fragment 782 ReflectionHelpers.setField(fragment, "mSavedFragmentState", fragmentState); 783 784 FragmentController.of(fragment, SettingsActivity.class).create( 785 R.id.main_content, /* bundle= */ null).start().resume().get(); 786 fragment.setupMagnificationEditShortcutDialog( 787 createEditShortcutDialog(fragment.getActivity())); 788 final int value = fragment.getShortcutTypeCheckBoxValue(); 789 fragment.saveNonEmptyUserShortcutType(value); 790 791 final int expectedType = PreferredShortcuts.retrieveUserShortcutType(mContext, 792 MAGNIFICATION_CONTROLLER_NAME); 793 assertThat(value).isEqualTo(UserShortcutType.TWOFINGER_DOUBLETAP); 794 assertThat(expectedType).isEqualTo(UserShortcutType.TWOFINGER_DOUBLETAP); 795 } 796 797 @Test onCreateView_magnificationAreaNotSupported_settingsPreferenceIsNull()798 public void onCreateView_magnificationAreaNotSupported_settingsPreferenceIsNull() { 799 setWindowMagnificationSupported( 800 /* magnificationAreaSupported= */ false, 801 /* windowMagnificationSupported= */ true); 802 803 mFragController.create(R.id.main_content, /* bundle= */ null).start().resume(); 804 805 assertThat(mFragController.get().mSettingsPreference).isNull(); 806 } 807 808 @Test onCreateView_windowMagnificationNotSupported_settingsPreferenceIsNull()809 public void onCreateView_windowMagnificationNotSupported_settingsPreferenceIsNull() { 810 setWindowMagnificationSupported( 811 /* magnificationAreaSupported= */ true, 812 /* windowMagnificationSupported= */ false); 813 814 mFragController.create(R.id.main_content, /* bundle= */ null).start().resume(); 815 816 assertThat(mFragController.get().mSettingsPreference).isNull(); 817 } 818 819 @Test 820 @DisableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE) onCreateView_oneFingerPanNotSupported_settingsPreferenceIsNull()821 public void onCreateView_oneFingerPanNotSupported_settingsPreferenceIsNull() { 822 mFragController.create(R.id.main_content, /* bundle= */ null).start().resume(); 823 824 final TwoStatePreference switchPreference = mFragController.get().findPreference( 825 MagnificationOneFingerPanningPreferenceController.PREF_KEY); 826 assertThat(switchPreference).isNull(); 827 } 828 829 @Test onCreateView_alwaysOnNotSupported_settingsPreferenceIsNull()830 public void onCreateView_alwaysOnNotSupported_settingsPreferenceIsNull() { 831 setAlwaysOnSupported(false); 832 833 mFragController.create(R.id.main_content, /* bundle= */ null).start().resume(); 834 835 final TwoStatePreference switchPreference = mFragController.get().findPreference( 836 MagnificationAlwaysOnPreferenceController.PREF_KEY); 837 assertThat(switchPreference).isNull(); 838 } 839 840 @Test onCreateView_joystickNotSupported_settingsPreferenceIsNull()841 public void onCreateView_joystickNotSupported_settingsPreferenceIsNull() { 842 setJoystickSupported(false); 843 844 mFragController.create(R.id.main_content, /* bundle= */ null).start().resume(); 845 846 final TwoStatePreference switchPreference = mFragController.get().findPreference( 847 MagnificationJoystickPreferenceController.PREF_KEY); 848 assertThat(switchPreference).isNull(); 849 } 850 851 @Test onCreateView_setDialogDelegateAndAddTheControllerToLifeCycleObserver()852 public void onCreateView_setDialogDelegateAndAddTheControllerToLifeCycleObserver() { 853 Correspondence instanceOf = Correspondence.transforming( 854 observer -> (observer instanceof MagnificationModePreferenceController), 855 "contains MagnificationModePreferenceController"); 856 857 ToggleScreenMagnificationPreferenceFragment fragment = mFragController.create( 858 R.id.main_content, /* bundle= */ null).start().resume().get(); 859 860 DialogCreatable dialogDelegate = ReflectionHelpers.getField(fragment, "mDialogDelegate"); 861 List<LifecycleObserver> lifecycleObservers = ReflectionHelpers.getField( 862 fragment.getSettingsLifecycle(), "mObservers"); 863 assertThat(dialogDelegate).isInstanceOf(MagnificationModePreferenceController.class); 864 assertThat(lifecycleObservers).isNotNull(); 865 assertThat(lifecycleObservers).comparingElementsUsing(instanceOf).contains(true); 866 } 867 868 @Test 869 @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE) onCreateView_oneFingerPanSupported_addControllerToLifeCycleObserver()870 public void onCreateView_oneFingerPanSupported_addControllerToLifeCycleObserver() { 871 Correspondence instanceOf = Correspondence.transforming( 872 observer -> (observer instanceof MagnificationOneFingerPanningPreferenceController), 873 "contains MagnificationOneFingerPanningPreferenceController"); 874 875 ToggleScreenMagnificationPreferenceFragment fragment = mFragController.create( 876 R.id.main_content, /* bundle= */ null).start().resume().get(); 877 878 List<LifecycleObserver> lifecycleObservers = ReflectionHelpers.getField( 879 fragment.getSettingsLifecycle(), "mObservers"); 880 assertThat(lifecycleObservers).isNotNull(); 881 assertThat(lifecycleObservers).comparingElementsUsing(instanceOf).contains(true); 882 } 883 884 @Test onCreateView_alwaysOnSupported_addControllerToLifeCycleObserver()885 public void onCreateView_alwaysOnSupported_addControllerToLifeCycleObserver() { 886 setAlwaysOnSupported(true); 887 888 Correspondence instanceOf = Correspondence.transforming( 889 observer -> (observer instanceof MagnificationAlwaysOnPreferenceController), 890 "contains MagnificationAlwaysOnPreferenceController"); 891 892 ToggleScreenMagnificationPreferenceFragment fragment = mFragController.create( 893 R.id.main_content, /* bundle= */ null).start().resume().get(); 894 895 List<LifecycleObserver> lifecycleObservers = ReflectionHelpers.getField( 896 fragment.getSettingsLifecycle(), "mObservers"); 897 assertThat(lifecycleObservers).isNotNull(); 898 assertThat(lifecycleObservers).comparingElementsUsing(instanceOf).contains(true); 899 } 900 901 @Test onCreateDialog_setDialogDelegate_invokeDialogDelegate()902 public void onCreateDialog_setDialogDelegate_invokeDialogDelegate() { 903 ToggleScreenMagnificationPreferenceFragment fragment = 904 mFragController.create( 905 R.id.main_content, /* bundle= */ null).start().resume().get(); 906 final DialogCreatable dialogDelegate = mock(DialogCreatable.class, RETURNS_DEEP_STUBS); 907 when(dialogDelegate.getDialogMetricsCategory(anyInt())).thenReturn(1); 908 fragment.setDialogDelegate(dialogDelegate); 909 910 fragment.onCreateDialog(1); 911 fragment.getDialogMetricsCategory(1); 912 913 verify(dialogDelegate).onCreateDialog(1); 914 verify(dialogDelegate).getDialogMetricsCategory(1); 915 } 916 917 @Test getMetricsCategory_returnsCorrectCategory()918 public void getMetricsCategory_returnsCorrectCategory() { 919 ToggleScreenMagnificationPreferenceFragment fragment = 920 mFragController.create( 921 R.id.main_content, /* bundle= */ null).start().resume().get(); 922 923 assertThat(fragment.getMetricsCategory()).isEqualTo( 924 SettingsEnums.ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFICATION); 925 } 926 927 @Test getHelpResource_returnsCorrectHelpResource()928 public void getHelpResource_returnsCorrectHelpResource() { 929 ToggleScreenMagnificationPreferenceFragment fragment = 930 mFragController.create( 931 R.id.main_content, /* bundle= */ null).start().resume().get(); 932 933 assertThat(fragment.getHelpResource()).isEqualTo(R.string.help_url_magnification); 934 } 935 936 @Test onProcessArguments_defaultArgumentUnavailable_shouldSetDefaultArguments()937 public void onProcessArguments_defaultArgumentUnavailable_shouldSetDefaultArguments() { 938 ToggleScreenMagnificationPreferenceFragment fragment = 939 mFragController.create( 940 R.id.main_content, /* bundle= */ null).start().resume().get(); 941 Bundle arguments = new Bundle(); 942 943 fragment.onProcessArguments(arguments); 944 945 assertTrue(arguments.containsKey(AccessibilitySettings.EXTRA_PREFERENCE_KEY)); 946 assertTrue(arguments.containsKey(AccessibilitySettings.EXTRA_INTRO)); 947 assertTrue(arguments.containsKey(AccessibilitySettings.EXTRA_HTML_DESCRIPTION)); 948 } 949 950 @Test getSummary_magnificationEnabled_returnShortcutOnWithSummary()951 public void getSummary_magnificationEnabled_returnShortcutOnWithSummary() { 952 setMagnificationTripleTapEnabled(true); 953 954 assertThat( 955 ToggleScreenMagnificationPreferenceFragment.getServiceSummary(mContext).toString()) 956 .isEqualTo( 957 mContext.getString(R.string.preference_summary_default_combination, 958 mContext.getText(R.string.accessibility_summary_shortcut_enabled), 959 mContext.getText(R.string.magnification_feature_summary))); 960 } 961 962 @Test getSummary_magnificationDisabled_returnShortcutOffWithSummary()963 public void getSummary_magnificationDisabled_returnShortcutOffWithSummary() { 964 setMagnificationTripleTapEnabled(false); 965 966 assertThat( 967 ToggleScreenMagnificationPreferenceFragment.getServiceSummary(mContext).toString()) 968 .isEqualTo( 969 mContext.getString(R.string.preference_summary_default_combination, 970 mContext.getText( 971 R.string.generic_accessibility_feature_shortcut_off), 972 mContext.getText(R.string.magnification_feature_summary))); 973 } 974 975 @Test 976 @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE) getSummary_magnificationGestureEnabled_returnShortcutOnWithSummary()977 public void getSummary_magnificationGestureEnabled_returnShortcutOnWithSummary() { 978 Settings.Secure.putInt( 979 mContext.getContentResolver(), TWO_FINGER_TRIPLE_TAP_SHORTCUT_KEY, ON); 980 981 assertThat( 982 ToggleScreenMagnificationPreferenceFragment.getServiceSummary(mContext).toString()) 983 .isEqualTo( 984 mContext.getString(R.string.preference_summary_default_combination, 985 mContext.getText(R.string.accessibility_summary_shortcut_enabled), 986 mContext.getText(R.string.magnification_feature_summary))); 987 } 988 989 @Test 990 @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE) getSummary_magnificationGestureDisabled_returnShortcutOffWithSummary()991 public void getSummary_magnificationGestureDisabled_returnShortcutOffWithSummary() { 992 Settings.Secure.putInt( 993 mContext.getContentResolver(), TWO_FINGER_TRIPLE_TAP_SHORTCUT_KEY, OFF); 994 995 assertThat( 996 ToggleScreenMagnificationPreferenceFragment.getServiceSummary(mContext).toString()) 997 .isEqualTo( 998 mContext.getString(R.string.preference_summary_default_combination, 999 mContext.getText( 1000 R.string.generic_accessibility_feature_shortcut_off), 1001 mContext.getText(R.string.magnification_feature_summary))); 1002 } 1003 1004 @Test 1005 @EnableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) getShortcutTypeSummary_shortcutSummaryIsCorrectlySet()1006 public void getShortcutTypeSummary_shortcutSummaryIsCorrectlySet() { 1007 final PreferredShortcut userPreferredShortcut = new PreferredShortcut( 1008 MAGNIFICATION_CONTROLLER_NAME, 1009 UserShortcutType.HARDWARE | UserShortcutType.QUICK_SETTINGS); 1010 putUserShortcutTypeIntoSharedPreference(mContext, userPreferredShortcut); 1011 final ShortcutPreference shortcutPreference = 1012 new ShortcutPreference(mContext, /* attrs= */ null); 1013 shortcutPreference.setChecked(true); 1014 shortcutPreference.setSettingsEditable(true); 1015 ToggleScreenMagnificationPreferenceFragment fragment = 1016 mFragController.create(R.id.main_content, /* bundle= */ 1017 null).start().resume().get(); 1018 fragment.mShortcutPreference = shortcutPreference; 1019 String expected = CaseMap.toTitle().wholeString().noLowercase().apply(Locale.getDefault(), 1020 /* iter= */ null, 1021 mContext.getString( 1022 R.string.accessibility_feature_shortcut_setting_summary_quick_settings) 1023 + ", " 1024 + mContext.getString(R.string.accessibility_shortcut_hardware_keyword)); 1025 1026 String summary = fragment.getShortcutTypeSummary(mContext).toString(); 1027 1028 assertThat(summary).isEqualTo(expected); 1029 } 1030 putStringIntoSettings(String key, String componentName)1031 private void putStringIntoSettings(String key, String componentName) { 1032 Settings.Secure.putString(mContext.getContentResolver(), key, componentName); 1033 } 1034 putUserShortcutTypeIntoSharedPreference(Context context, PreferredShortcut shortcut)1035 private void putUserShortcutTypeIntoSharedPreference(Context context, 1036 PreferredShortcut shortcut) { 1037 PreferredShortcuts.saveUserShortcutType(context, shortcut); 1038 } 1039 setMagnificationTripleTapEnabled(boolean enabled)1040 private void setMagnificationTripleTapEnabled(boolean enabled) { 1041 Settings.Secure.putInt(mContext.getContentResolver(), TRIPLETAP_SHORTCUT_KEY, 1042 enabled ? ON : OFF); 1043 } 1044 setKeyMagnificationMode(@agnificationMode int mode)1045 private void setKeyMagnificationMode(@MagnificationMode int mode) { 1046 MagnificationCapabilities.setCapabilities(mContext, mode); 1047 } 1048 setKeyFollowTypingEnabled(boolean enabled)1049 private void setKeyFollowTypingEnabled(boolean enabled) { 1050 Settings.Secure.putInt(mContext.getContentResolver(), KEY_FOLLOW_TYPING, 1051 enabled ? ON : OFF); 1052 } 1053 setKeyOneFingerPanEnabled(boolean enabled)1054 private void setKeyOneFingerPanEnabled(boolean enabled) { 1055 Settings.Secure.putInt(mContext.getContentResolver(), KEY_SINGLE_FINGER_PANNING, 1056 enabled ? ON : OFF); 1057 } 1058 setAlwaysOnSupported(boolean supported)1059 private void setAlwaysOnSupported(boolean supported) { 1060 ShadowDeviceConfig.setProperty( 1061 DeviceConfig.NAMESPACE_WINDOW_MANAGER, 1062 "AlwaysOnMagnifier__enable_always_on_magnifier", 1063 supported ? "true" : "false", 1064 /* makeDefault= */ false); 1065 } 1066 setKeyAlwaysOnEnabled(boolean enabled)1067 private void setKeyAlwaysOnEnabled(boolean enabled) { 1068 Settings.Secure.putInt(mContext.getContentResolver(), KEY_ALWAYS_ON, 1069 enabled ? ON : OFF); 1070 } 1071 setJoystickSupported(boolean supported)1072 private void setJoystickSupported(boolean supported) { 1073 ShadowDeviceConfig.setProperty( 1074 DeviceConfig.NAMESPACE_WINDOW_MANAGER, 1075 "MagnificationJoystick__enable_magnification_joystick", 1076 supported ? "true" : "false", 1077 /* makeDefault= */ false); 1078 } 1079 setKeyJoystickEnabled(boolean enabled)1080 private void setKeyJoystickEnabled(boolean enabled) { 1081 Settings.Secure.putInt(mContext.getContentResolver(), KEY_JOYSTICK, 1082 enabled ? ON : OFF); 1083 } 1084 getStringFromSettings(String key)1085 private String getStringFromSettings(String key) { 1086 return Settings.Secure.getString(mContext.getContentResolver(), key); 1087 } 1088 getMagnificationTripleTapStatus()1089 private boolean getMagnificationTripleTapStatus() { 1090 return Settings.Secure.getInt(mContext.getContentResolver(), TRIPLETAP_SHORTCUT_KEY, OFF) 1091 == ON; 1092 } 1093 callEmptyOnClicked(DialogInterface dialog, int which)1094 private void callEmptyOnClicked(DialogInterface dialog, int which) { 1095 } 1096 setWindowMagnificationSupported(boolean magnificationAreaSupported, boolean windowMagnificationSupported)1097 private void setWindowMagnificationSupported(boolean magnificationAreaSupported, 1098 boolean windowMagnificationSupported) { 1099 when(mSpyResources.getBoolean( 1100 com.android.internal.R.bool.config_magnification_area)) 1101 .thenReturn(magnificationAreaSupported); 1102 mShadowPackageManager.setSystemFeature(PackageManager.FEATURE_WINDOW_MAGNIFICATION, 1103 windowMagnificationSupported); 1104 } 1105 createEditShortcutDialog(Context context)1106 private AlertDialog createEditShortcutDialog(Context context) { 1107 context.setTheme(androidx.appcompat.R.style.Theme_AppCompat); 1108 return AccessibilityDialogUtils.showEditShortcutDialog( 1109 context, 1110 DialogType.EDIT_SHORTCUT_MAGNIFICATION, PLACEHOLDER_DIALOG_TITLE, 1111 this::callEmptyOnClicked); 1112 } 1113 createFragmentSavedInstanceState(int userShortcutType)1114 private Bundle createFragmentSavedInstanceState(int userShortcutType) { 1115 final Bundle savedInstanceState = new Bundle(); 1116 savedInstanceState.putInt(KEY_SAVED_USER_SHORTCUT_TYPE, userShortcutType); 1117 final Bundle fragmentState = new Bundle(); 1118 fragmentState.putBundle( 1119 /* FragmentStateManager.SAVED_INSTANCE_STATE_KEY */ "savedInstanceState", 1120 savedInstanceState); 1121 return fragmentState; 1122 } 1123 1124 /** 1125 * A test fragment that provides a way to change the context 1126 */ 1127 public static class TestToggleScreenMagnificationPreferenceFragment 1128 extends ToggleScreenMagnificationPreferenceFragment { 1129 private Context mContext; 1130 1131 @Override getContext()1132 public Context getContext() { 1133 return this.mContext != null ? this.mContext : super.getContext(); 1134 } 1135 1136 /** 1137 * Sets the spy context used for RoboTest in order to change the value of 1138 * com.android.internal.R.bool.config_magnification_area 1139 */ setContext(Context context)1140 public void setContext(Context context) { 1141 this.mContext = context; 1142 } 1143 } 1144 } 1145