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.AccessibilityShortcutsTutorial.createAccessibilityTutorialDialog; 20 import static com.android.settings.accessibility.AccessibilityShortcutsTutorial.createAccessibilityTutorialDialogForSetupWizard; 21 import static com.android.settings.accessibility.AccessibilityShortcutsTutorial.createShortcutTutorialPages; 22 import static com.android.settings.accessibility.AccessibilityShortcutsTutorial.showGestureNavigationTutorialDialog; 23 import static com.android.settings.accessibility.AccessibilityUtil.UserShortcutType; 24 25 import static com.google.common.truth.Truth.assertThat; 26 27 import static org.mockito.Mockito.verify; 28 import static org.robolectric.Shadows.shadowOf; 29 30 import android.app.Activity; 31 import android.app.settings.SettingsEnums; 32 import android.content.Context; 33 import android.content.DialogInterface; 34 import android.content.Intent; 35 import android.platform.test.annotations.EnableFlags; 36 import android.platform.test.flag.junit.SetFlagsRule; 37 import android.text.SpannableStringBuilder; 38 import android.util.ArrayMap; 39 import android.view.View; 40 import android.view.accessibility.AccessibilityManager; 41 import android.widget.Button; 42 import android.widget.TextSwitcher; 43 import android.widget.TextView; 44 45 import androidx.appcompat.app.AlertDialog; 46 import androidx.test.core.app.ApplicationProvider; 47 48 import com.android.server.accessibility.Flags; 49 import com.android.settings.R; 50 import com.android.settings.SettingsActivity; 51 import com.android.settings.SubSettings; 52 import com.android.settings.testutils.AccessibilityTestUtils; 53 import com.android.settings.testutils.shadow.SettingsShadowResources; 54 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; 55 import com.android.settingslib.utils.StringUtil; 56 57 import org.junit.Before; 58 import org.junit.Rule; 59 import org.junit.Test; 60 import org.junit.runner.RunWith; 61 import org.mockito.Mock; 62 import org.mockito.junit.MockitoJUnit; 63 import org.mockito.junit.MockitoRule; 64 import org.robolectric.Robolectric; 65 import org.robolectric.RobolectricTestRunner; 66 import org.robolectric.annotation.Config; 67 import org.robolectric.shadows.ShadowAccessibilityManager; 68 import org.robolectric.shadows.ShadowLooper; 69 70 import java.util.Map; 71 72 /** Tests for {@link AccessibilityShortcutsTutorial}. */ 73 @Config(shadows = SettingsShadowResources.class) 74 @RunWith(RobolectricTestRunner.class) 75 public final class AccessibilityShortcutsTutorialTest { 76 private static final String FAKE_FEATURE_NAME = "Fake Feature Name"; 77 78 @Rule 79 public final MockitoRule mMockitoRule = MockitoJUnit.rule(); 80 @Rule 81 public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); 82 @Mock 83 private DialogInterface.OnClickListener mOnClickListener; 84 @Mock 85 private DialogInterface.OnDismissListener mOnDismissListener; 86 private final Context mContext = ApplicationProvider.getApplicationContext(); 87 private int mShortcutTypes; 88 89 @Before setUp()90 public void setUp() { 91 mContext.setTheme(androidx.appcompat.R.style.Theme_AppCompat); 92 mShortcutTypes = /* initial */ 0; 93 } 94 95 @Test(expected = IllegalArgumentException.class) createTutorialPages_shortcutListIsEmpty_throwsException()96 public void createTutorialPages_shortcutListIsEmpty_throwsException() { 97 createAccessibilityTutorialDialog(mContext, mShortcutTypes, FAKE_FEATURE_NAME); 98 } 99 100 @Test createTutorialPages_turnOnTripleTapShortcut_hasOnePage()101 public void createTutorialPages_turnOnTripleTapShortcut_hasOnePage() { 102 mShortcutTypes |= UserShortcutType.TRIPLETAP; 103 104 final AlertDialog alertDialog = 105 createAccessibilityTutorialDialog(mContext, mShortcutTypes, FAKE_FEATURE_NAME); 106 107 assertThat( 108 createShortcutTutorialPages( 109 mContext, mShortcutTypes, FAKE_FEATURE_NAME, /* inSetupWizard= */ false) 110 ).hasSize(/* expectedSize= */ 1); 111 assertThat(alertDialog).isNotNull(); 112 } 113 114 @Test 115 @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE) createTutorialPages_turnOnTwoFingerTripleTapShortcut_hasOnePage()116 public void createTutorialPages_turnOnTwoFingerTripleTapShortcut_hasOnePage() { 117 mShortcutTypes |= UserShortcutType.TWOFINGER_DOUBLETAP; 118 119 final AlertDialog alertDialog = 120 createAccessibilityTutorialDialog(mContext, mShortcutTypes, FAKE_FEATURE_NAME); 121 122 assertThat( 123 createShortcutTutorialPages( 124 mContext, mShortcutTypes, FAKE_FEATURE_NAME, /* inSetupWizard= */ false) 125 ).hasSize(/* expectedSize= */ 1); 126 assertThat(alertDialog).isNotNull(); 127 } 128 129 @Test 130 @EnableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) createTutorialPages_turnOnQuickSettingShortcut_hasOnePage()131 public void createTutorialPages_turnOnQuickSettingShortcut_hasOnePage() { 132 mShortcutTypes |= UserShortcutType.QUICK_SETTINGS; 133 134 final AlertDialog alertDialog = 135 createAccessibilityTutorialDialog(mContext, mShortcutTypes, FAKE_FEATURE_NAME); 136 137 assertThat( 138 createShortcutTutorialPages( 139 mContext, mShortcutTypes, FAKE_FEATURE_NAME, /* inSetupWizard= */ false) 140 ).hasSize(/* expectedSize= */ 1); 141 assertThat(alertDialog).isNotNull(); 142 } 143 144 @Test createTutorialPages_turnOnSoftwareShortcut_hasOnePage()145 public void createTutorialPages_turnOnSoftwareShortcut_hasOnePage() { 146 mShortcutTypes |= UserShortcutType.SOFTWARE; 147 148 final AlertDialog alertDialog = 149 createAccessibilityTutorialDialog(mContext, mShortcutTypes, FAKE_FEATURE_NAME); 150 151 assertThat( 152 createShortcutTutorialPages( 153 mContext, mShortcutTypes, FAKE_FEATURE_NAME, /* inSetupWizard= */ false) 154 ).hasSize(/* expectedSize= */ 1); 155 assertThat(alertDialog).isNotNull(); 156 } 157 158 @Test createTutorialPages_turnOnSoftwareAndHardwareShortcuts_hasTwoPages()159 public void createTutorialPages_turnOnSoftwareAndHardwareShortcuts_hasTwoPages() { 160 mShortcutTypes |= UserShortcutType.SOFTWARE; 161 mShortcutTypes |= UserShortcutType.HARDWARE; 162 163 final AlertDialog alertDialog = 164 createAccessibilityTutorialDialog(mContext, mShortcutTypes, FAKE_FEATURE_NAME); 165 166 assertThat( 167 createShortcutTutorialPages( 168 mContext, mShortcutTypes, FAKE_FEATURE_NAME, /* inSetupWizard= */ false) 169 ).hasSize(/* expectedSize= */ 2); 170 assertThat(alertDialog).isNotNull(); 171 } 172 173 @Test createTutorialPages_turnOnA11yGestureShortcut_linkButtonShownWithText()174 public void createTutorialPages_turnOnA11yGestureShortcut_linkButtonShownWithText() { 175 mShortcutTypes |= UserShortcutType.SOFTWARE; 176 AccessibilityTestUtils.setSoftwareShortcutMode( 177 mContext, /* gestureNavEnabled= */ true, /* floatingButtonEnabled= */ false); 178 179 final AlertDialog alertDialog = 180 createAccessibilityTutorialDialog(mContext, mShortcutTypes, FAKE_FEATURE_NAME); 181 alertDialog.show(); 182 ShadowLooper.idleMainLooper(); 183 184 Button btn = alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE); 185 assertThat(btn).isNotNull(); 186 assertThat(btn.getVisibility()).isEqualTo(View.VISIBLE); 187 assertThat(btn.getText().toString()).isEqualTo( 188 mContext.getString( 189 R.string.accessibility_tutorial_dialog_configure_software_shortcut_type)); 190 } 191 192 @Test createTutorialPages_turnOnA11yNavButtonShortcut_linkButtonShownWithText()193 public void createTutorialPages_turnOnA11yNavButtonShortcut_linkButtonShownWithText() { 194 mShortcutTypes |= UserShortcutType.SOFTWARE; 195 AccessibilityTestUtils.setSoftwareShortcutMode( 196 mContext, /* gestureNavEnabled= */ false, /* floatingButtonEnabled= */ false); 197 198 final AlertDialog alertDialog = 199 createAccessibilityTutorialDialog(mContext, mShortcutTypes, FAKE_FEATURE_NAME); 200 alertDialog.show(); 201 ShadowLooper.idleMainLooper(); 202 203 Button btn = alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE); 204 assertThat(btn).isNotNull(); 205 assertThat(btn.getVisibility()).isEqualTo(View.VISIBLE); 206 assertThat(btn.getText().toString()).isEqualTo( 207 mContext.getString( 208 R.string.accessibility_tutorial_dialog_configure_software_shortcut_type)); 209 } 210 211 @Test createTutorialPages_turnOnFloatingButtonShortcut_linkButtonShownWithText()212 public void createTutorialPages_turnOnFloatingButtonShortcut_linkButtonShownWithText() { 213 mShortcutTypes |= UserShortcutType.SOFTWARE; 214 AccessibilityTestUtils.setSoftwareShortcutMode( 215 mContext, /* gestureNavEnabled= */ false, /* floatingButtonEnabled= */ true); 216 217 final AlertDialog alertDialog = 218 createAccessibilityTutorialDialog(mContext, mShortcutTypes, FAKE_FEATURE_NAME); 219 alertDialog.show(); 220 ShadowLooper.idleMainLooper(); 221 222 Button btn = alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE); 223 assertThat(btn).isNotNull(); 224 assertThat(btn.getVisibility()).isEqualTo(View.VISIBLE); 225 assertThat(btn.getText().toString()).isEqualTo( 226 mContext.getString(R.string.accessibility_tutorial_dialog_link_button)); 227 } 228 229 @Test createTutorialPages_turnOnHardwareShortcut_linkButtonGone()230 public void createTutorialPages_turnOnHardwareShortcut_linkButtonGone() { 231 mShortcutTypes |= UserShortcutType.HARDWARE; 232 233 final AlertDialog alertDialog = 234 createAccessibilityTutorialDialog(mContext, mShortcutTypes, FAKE_FEATURE_NAME); 235 alertDialog.show(); 236 ShadowLooper.idleMainLooper(); 237 238 assertThat(alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE).getVisibility()) 239 .isEqualTo(View.GONE); 240 } 241 242 @Test createTutorialPages_turnOnSoftwareShortcut_showFromSuW_linkButtonGone()243 public void createTutorialPages_turnOnSoftwareShortcut_showFromSuW_linkButtonGone() { 244 mShortcutTypes |= UserShortcutType.SOFTWARE; 245 246 final AlertDialog alertDialog = 247 createAccessibilityTutorialDialogForSetupWizard( 248 mContext, mShortcutTypes, FAKE_FEATURE_NAME); 249 alertDialog.show(); 250 ShadowLooper.idleMainLooper(); 251 252 assertThat(alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE).getVisibility()) 253 .isEqualTo(View.GONE); 254 } 255 256 @Test 257 @EnableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) createAccessibilityTutorialDialog_qsShortcut_inSuwTalkbackOn_verifyText()258 public void createAccessibilityTutorialDialog_qsShortcut_inSuwTalkbackOn_verifyText() { 259 mShortcutTypes |= UserShortcutType.QUICK_SETTINGS; 260 setTouchExplorationEnabled(true); 261 final String expectedTitle = mContext.getString( 262 R.string.accessibility_tutorial_dialog_title_quick_setting); 263 Map<String, Object> arguments = new ArrayMap<>(); 264 arguments.put("count", 2); 265 arguments.put("featureName", FAKE_FEATURE_NAME); 266 final CharSequence instruction = StringUtil.getIcuPluralsString(mContext, 267 arguments, 268 R.string.accessibility_tutorial_dialog_message_quick_setting); 269 final SpannableStringBuilder expectedInstruction = new SpannableStringBuilder(); 270 expectedInstruction 271 .append(mContext.getText( 272 R.string.accessibility_tutorial_dialog_shortcut_unavailable_in_suw)) 273 .append("\n\n"); 274 expectedInstruction.append(instruction); 275 276 final AlertDialog alertDialog = 277 createAccessibilityTutorialDialogForSetupWizard( 278 mContext, mShortcutTypes, FAKE_FEATURE_NAME); 279 alertDialog.show(); 280 ShadowLooper.idleMainLooper(); 281 282 verifyTutorialTitleAndInstruction( 283 alertDialog, 284 expectedTitle, 285 expectedInstruction.toString()); 286 } 287 288 @Test 289 @EnableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) createAccessibilityTutorialDialog_qsShortcut_notInSuwTalkbackOn_verifyText()290 public void createAccessibilityTutorialDialog_qsShortcut_notInSuwTalkbackOn_verifyText() { 291 mShortcutTypes |= UserShortcutType.QUICK_SETTINGS; 292 setTouchExplorationEnabled(true); 293 final String expectedTitle = mContext.getString( 294 R.string.accessibility_tutorial_dialog_title_quick_setting); 295 Map<String, Object> arguments = new ArrayMap<>(); 296 arguments.put("count", 2); 297 arguments.put("featureName", FAKE_FEATURE_NAME); 298 final CharSequence expectedInstruction = StringUtil.getIcuPluralsString(mContext, 299 arguments, 300 R.string.accessibility_tutorial_dialog_message_quick_setting); 301 302 final AlertDialog alertDialog = 303 createAccessibilityTutorialDialog( 304 mContext, mShortcutTypes, FAKE_FEATURE_NAME); 305 alertDialog.show(); 306 ShadowLooper.idleMainLooper(); 307 308 verifyTutorialTitleAndInstruction( 309 alertDialog, 310 expectedTitle, 311 expectedInstruction.toString()); 312 } 313 314 @Test 315 @EnableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) createAccessibilityTutorialDialog_qsShortcut_inSuwTalkbackOff_verifyText()316 public void createAccessibilityTutorialDialog_qsShortcut_inSuwTalkbackOff_verifyText() { 317 mShortcutTypes |= UserShortcutType.QUICK_SETTINGS; 318 setTouchExplorationEnabled(false); 319 final String expectedTitle = mContext.getString( 320 R.string.accessibility_tutorial_dialog_title_quick_setting); 321 Map<String, Object> arguments = new ArrayMap<>(); 322 arguments.put("count", 1); 323 arguments.put("featureName", FAKE_FEATURE_NAME); 324 final CharSequence instruction = StringUtil.getIcuPluralsString(mContext, 325 arguments, 326 R.string.accessibility_tutorial_dialog_message_quick_setting); 327 final SpannableStringBuilder expectedInstruction = new SpannableStringBuilder(); 328 expectedInstruction.append(mContext.getText( 329 R.string.accessibility_tutorial_dialog_shortcut_unavailable_in_suw)) 330 .append("\n\n"); 331 expectedInstruction.append(instruction); 332 333 final AlertDialog alertDialog = 334 createAccessibilityTutorialDialogForSetupWizard( 335 mContext, mShortcutTypes, FAKE_FEATURE_NAME); 336 alertDialog.show(); 337 ShadowLooper.idleMainLooper(); 338 339 verifyTutorialTitleAndInstruction( 340 alertDialog, 341 expectedTitle, 342 expectedInstruction.toString()); 343 } 344 345 @Test 346 @EnableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) createAccessibilityTutorialDialog_qsShortcut_notInSuwTalkbackOff_verifyText()347 public void createAccessibilityTutorialDialog_qsShortcut_notInSuwTalkbackOff_verifyText() { 348 mShortcutTypes |= UserShortcutType.QUICK_SETTINGS; 349 setTouchExplorationEnabled(false); 350 final String expectedTitle = mContext.getString( 351 R.string.accessibility_tutorial_dialog_title_quick_setting); 352 Map<String, Object> arguments = new ArrayMap<>(); 353 arguments.put("count", 1); 354 arguments.put("featureName", FAKE_FEATURE_NAME); 355 final CharSequence expectedInstruction = StringUtil.getIcuPluralsString(mContext, 356 arguments, 357 R.string.accessibility_tutorial_dialog_message_quick_setting); 358 359 final AlertDialog alertDialog = 360 createAccessibilityTutorialDialog( 361 mContext, mShortcutTypes, FAKE_FEATURE_NAME); 362 alertDialog.show(); 363 ShadowLooper.idleMainLooper(); 364 365 verifyTutorialTitleAndInstruction( 366 alertDialog, 367 expectedTitle, 368 expectedInstruction.toString()); 369 } 370 371 @Test createAccessibilityTutorialDialog_volumeKeysShortcut_verifyText()372 public void createAccessibilityTutorialDialog_volumeKeysShortcut_verifyText() { 373 mShortcutTypes |= UserShortcutType.HARDWARE; 374 final String expectedTitle = mContext.getString( 375 R.string.accessibility_tutorial_dialog_title_volume); 376 final CharSequence expectedInstruction = mContext.getString( 377 R.string.accessibility_tutorial_dialog_message_volume); 378 379 final AlertDialog alertDialog = 380 createAccessibilityTutorialDialog( 381 mContext, mShortcutTypes, FAKE_FEATURE_NAME); 382 alertDialog.show(); 383 ShadowLooper.idleMainLooper(); 384 385 verifyTutorialTitleAndInstruction( 386 alertDialog, 387 expectedTitle, 388 expectedInstruction.toString()); 389 } 390 391 @Test createAccessibilityTutorialDialog_tripleTapShortcut_verifyText()392 public void createAccessibilityTutorialDialog_tripleTapShortcut_verifyText() { 393 mShortcutTypes |= UserShortcutType.TRIPLETAP; 394 final String expectedTitle = mContext.getString( 395 R.string.accessibility_tutorial_dialog_title_triple); 396 final CharSequence expectedInstruction = mContext.getString( 397 R.string.accessibility_tutorial_dialog_tripletap_instruction, 3); 398 399 final AlertDialog alertDialog = 400 createAccessibilityTutorialDialog( 401 mContext, mShortcutTypes, FAKE_FEATURE_NAME); 402 alertDialog.show(); 403 ShadowLooper.idleMainLooper(); 404 405 verifyTutorialTitleAndInstruction( 406 alertDialog, 407 expectedTitle, 408 expectedInstruction.toString()); 409 } 410 411 @Test 412 @EnableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_MULTIPLE_FINGER_MULTIPLE_TAP_GESTURE) createAccessibilityTutorialDialog_twoFingerDoubleTapShortcut_verifyText()413 public void createAccessibilityTutorialDialog_twoFingerDoubleTapShortcut_verifyText() { 414 mShortcutTypes |= UserShortcutType.TWOFINGER_DOUBLETAP; 415 final int numFingers = 2; 416 final String expectedTitle = mContext.getString( 417 R.string.accessibility_tutorial_dialog_title_two_finger_double, numFingers); 418 final String expectedInstruction = mContext.getString( 419 R.string.accessibility_tutorial_dialog_twofinger_doubletap_instruction, numFingers); 420 421 final AlertDialog alertDialog = 422 createAccessibilityTutorialDialog( 423 mContext, mShortcutTypes, FAKE_FEATURE_NAME); 424 alertDialog.show(); 425 ShadowLooper.idleMainLooper(); 426 427 verifyTutorialTitleAndInstruction( 428 alertDialog, 429 expectedTitle, 430 expectedInstruction); 431 } 432 433 @Test createAccessibilityTutorialDialog_floatingButtonShortcut_verifyText()434 public void createAccessibilityTutorialDialog_floatingButtonShortcut_verifyText() { 435 mShortcutTypes |= UserShortcutType.SOFTWARE; 436 AccessibilityTestUtils.setSoftwareShortcutMode( 437 mContext, /* gestureNavEnabled= */ false, /* floatingButtonEnabled= */ true); 438 final String expectedTitle = mContext.getString( 439 R.string.accessibility_tutorial_dialog_title_button); 440 final String expectedInstruction = mContext.getString( 441 R.string.accessibility_tutorial_dialog_message_floating_button); 442 443 final AlertDialog alertDialog = 444 createAccessibilityTutorialDialog( 445 mContext, mShortcutTypes, FAKE_FEATURE_NAME); 446 alertDialog.show(); 447 ShadowLooper.idleMainLooper(); 448 449 verifyTutorialTitleAndInstruction( 450 alertDialog, 451 expectedTitle, 452 expectedInstruction); 453 } 454 455 @Test createAccessibilityTutorialDialog_navA11yButtonShortcut_verifyText()456 public void createAccessibilityTutorialDialog_navA11yButtonShortcut_verifyText() { 457 mShortcutTypes |= UserShortcutType.SOFTWARE; 458 AccessibilityTestUtils.setSoftwareShortcutMode( 459 mContext, /* gestureNavEnabled= */ false, /* floatingButtonEnabled= */ false); 460 final String expectedTitle = mContext.getString( 461 R.string.accessibility_tutorial_dialog_title_button); 462 final String expectedInstruction = mContext.getString( 463 R.string.accessibility_tutorial_dialog_message_button); 464 465 final AlertDialog alertDialog = 466 createAccessibilityTutorialDialog( 467 mContext, mShortcutTypes, FAKE_FEATURE_NAME); 468 alertDialog.show(); 469 ShadowLooper.idleMainLooper(); 470 471 verifyTutorialTitleAndInstruction( 472 alertDialog, 473 expectedTitle, 474 expectedInstruction); 475 } 476 477 @Test createAccessibilityTutorialDialog_gestureShortcut_talkbackOn_verifyText()478 public void createAccessibilityTutorialDialog_gestureShortcut_talkbackOn_verifyText() { 479 mShortcutTypes |= UserShortcutType.SOFTWARE; 480 setTouchExplorationEnabled(true); 481 AccessibilityTestUtils.setSoftwareShortcutMode( 482 mContext, /* gestureNavEnabled= */ true, /* floatingButtonEnabled= */ false); 483 final String expectedTitle = mContext.getString( 484 R.string.accessibility_tutorial_dialog_title_gesture); 485 final String expectedInstruction = StringUtil.getIcuPluralsString( 486 mContext, 487 /* count= */ 3, 488 R.string.accessibility_tutorial_dialog_gesture_shortcut_instruction); 489 490 final AlertDialog alertDialog = 491 createAccessibilityTutorialDialog( 492 mContext, mShortcutTypes, FAKE_FEATURE_NAME); 493 alertDialog.show(); 494 ShadowLooper.idleMainLooper(); 495 496 verifyTutorialTitleAndInstruction( 497 alertDialog, 498 expectedTitle, 499 expectedInstruction); 500 } 501 502 @Test createAccessibilityTutorialDialog_gestureShortcut_talkbackOff_verifyText()503 public void createAccessibilityTutorialDialog_gestureShortcut_talkbackOff_verifyText() { 504 mShortcutTypes |= UserShortcutType.SOFTWARE; 505 setTouchExplorationEnabled(false); 506 AccessibilityTestUtils.setSoftwareShortcutMode( 507 mContext, /* gestureNavEnabled= */ true, /* floatingButtonEnabled= */ false); 508 final String expectedTitle = mContext.getString( 509 R.string.accessibility_tutorial_dialog_title_gesture); 510 final String expectedInstruction = StringUtil.getIcuPluralsString( 511 mContext, 512 /* count= */ 2, 513 R.string.accessibility_tutorial_dialog_gesture_shortcut_instruction); 514 515 final AlertDialog alertDialog = 516 createAccessibilityTutorialDialog( 517 mContext, mShortcutTypes, FAKE_FEATURE_NAME); 518 alertDialog.show(); 519 ShadowLooper.idleMainLooper(); 520 521 verifyTutorialTitleAndInstruction( 522 alertDialog, 523 expectedTitle, 524 expectedInstruction); 525 } 526 527 @Test performClickOnPositiveButton_turnOnSoftwareShortcut_dismiss()528 public void performClickOnPositiveButton_turnOnSoftwareShortcut_dismiss() { 529 mShortcutTypes |= UserShortcutType.SOFTWARE; 530 final AlertDialog alertDialog = 531 createAccessibilityTutorialDialog(mContext, mShortcutTypes, FAKE_FEATURE_NAME); 532 alertDialog.show(); 533 ShadowLooper.idleMainLooper(); 534 535 alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick(); 536 ShadowLooper.idleMainLooper(); 537 538 assertThat(alertDialog.isShowing()).isFalse(); 539 } 540 541 @Test performClickOnPositiveButton_turnOnSoftwareShortcut_callOnClickListener()542 public void performClickOnPositiveButton_turnOnSoftwareShortcut_callOnClickListener() { 543 mShortcutTypes |= UserShortcutType.SOFTWARE; 544 final AlertDialog alertDialog = 545 createAccessibilityTutorialDialog( 546 mContext, mShortcutTypes, mOnClickListener, FAKE_FEATURE_NAME); 547 alertDialog.show(); 548 ShadowLooper.idleMainLooper(); 549 550 alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick(); 551 ShadowLooper.idleMainLooper(); 552 553 verify(mOnClickListener).onClick(alertDialog, DialogInterface.BUTTON_POSITIVE); 554 } 555 556 @Test performClickOnNegativeButton_turnOnSoftwareShortcut_directToSettingsPage()557 public void performClickOnNegativeButton_turnOnSoftwareShortcut_directToSettingsPage() { 558 mShortcutTypes |= UserShortcutType.SOFTWARE; 559 Activity activity = Robolectric.buildActivity(Activity.class).create().get(); 560 final AlertDialog alertDialog = 561 createAccessibilityTutorialDialog(activity, mShortcutTypes, FAKE_FEATURE_NAME); 562 alertDialog.show(); 563 564 alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE).performClick(); 565 ShadowLooper.idleMainLooper(); 566 567 final Intent intent = shadowOf(activity).peekNextStartedActivity(); 568 assertThat(intent.getComponent().getClassName()).isEqualTo(SubSettings.class.getName()); 569 assertThat(intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT)) 570 .isEqualTo(AccessibilityButtonFragment.class.getName()); 571 assertThat(intent.getIntExtra(MetricsFeatureProvider.EXTRA_SOURCE_METRICS_CATEGORY, -1)) 572 .isEqualTo(SettingsEnums.SWITCH_SHORTCUT_DIALOG_ACCESSIBILITY_BUTTON_SETTINGS); 573 } 574 575 @Test performClickOnPositiveButton_turnOnGestureShortcut_callOnDismissListener()576 public void performClickOnPositiveButton_turnOnGestureShortcut_callOnDismissListener() { 577 final AlertDialog alertDialog = 578 showGestureNavigationTutorialDialog(mContext, mOnDismissListener); 579 580 alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick(); 581 ShadowLooper.idleMainLooper(); 582 583 assertThat(alertDialog.isShowing()).isFalse(); 584 verify(mOnDismissListener).onDismiss(alertDialog); 585 } 586 setTouchExplorationEnabled(boolean enable)587 private void setTouchExplorationEnabled(boolean enable) { 588 ShadowAccessibilityManager am = shadowOf( 589 mContext.getSystemService(AccessibilityManager.class)); 590 am.setTouchExplorationEnabled(enable); 591 } 592 verifyTutorialTitleAndInstruction(AlertDialog alertDialog, String expectedTitle, String expectedInstruction)593 private void verifyTutorialTitleAndInstruction(AlertDialog alertDialog, String expectedTitle, 594 String expectedInstruction) { 595 TextSwitcher titleView = alertDialog.findViewById(R.id.title); 596 assertThat(titleView).isNotNull(); 597 assertThat(((TextView) titleView.getCurrentView()).getText().toString()).isEqualTo( 598 expectedTitle); 599 TextSwitcher instructionView = alertDialog.findViewById(R.id.instruction); 600 assertThat(instructionView).isNotNull(); 601 assertThat(((TextView) instructionView.getCurrentView()).getText().toString()).isEqualTo( 602 expectedInstruction); 603 } 604 } 605