1 /* 2 * Copyright 2016, 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.managedprovisioning.provisioning; 18 19 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_FINANCED_DEVICE; 20 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE; 21 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE; 22 import static android.app.admin.DevicePolicyManager.ACTION_STATE_USER_SETUP_COMPLETE; 23 24 import static androidx.test.espresso.Espresso.onView; 25 import static androidx.test.espresso.Espresso.pressBack; 26 import static androidx.test.espresso.action.ViewActions.click; 27 import static androidx.test.espresso.assertion.ViewAssertions.matches; 28 import static androidx.test.espresso.intent.Intents.intended; 29 import static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction; 30 import static androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent; 31 import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; 32 import static androidx.test.espresso.matcher.ViewMatchers.withId; 33 import static androidx.test.espresso.matcher.ViewMatchers.withParent; 34 import static androidx.test.espresso.matcher.ViewMatchers.withText; 35 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; 36 37 import static com.google.common.truth.Truth.assertThat; 38 39 import static org.hamcrest.Matchers.not; 40 import static org.hamcrest.core.AllOf.allOf; 41 import static org.junit.Assert.assertFalse; 42 import static org.junit.Assert.assertTrue; 43 import static org.mockito.Matchers.any; 44 import static org.mockito.Matchers.anyString; 45 import static org.mockito.Matchers.eq; 46 import static org.mockito.Mockito.doNothing; 47 import static org.mockito.Mockito.doReturn; 48 import static org.mockito.Mockito.mockingDetails; 49 import static org.mockito.Mockito.reset; 50 import static org.mockito.Mockito.spy; 51 import static org.mockito.Mockito.timeout; 52 import static org.mockito.Mockito.verify; 53 import static org.mockito.Mockito.when; 54 55 import android.Manifest.permission; 56 import android.content.ComponentName; 57 import android.content.Context; 58 import android.content.Intent; 59 import android.content.pm.ActivityInfo; 60 import android.content.pm.PackageManager; 61 import android.content.pm.ResolveInfo; 62 import android.graphics.Color; 63 import android.os.Bundle; 64 import android.os.RemoteException; 65 import android.provider.Settings; 66 import android.support.test.uiautomator.UiDevice; 67 68 import androidx.test.InstrumentationRegistry; 69 import androidx.test.espresso.intent.Intents; 70 import androidx.test.espresso.intent.rule.IntentsTestRule; 71 import androidx.test.filters.SmallTest; 72 73 import com.android.managedprovisioning.R; 74 import com.android.managedprovisioning.TestInstrumentationRunner; 75 import com.android.managedprovisioning.TestUtils; 76 import com.android.managedprovisioning.common.LogoUtils; 77 import com.android.managedprovisioning.common.PolicyComplianceUtils; 78 import com.android.managedprovisioning.common.SettingsFacade; 79 import com.android.managedprovisioning.common.ThemeHelper; 80 import com.android.managedprovisioning.common.ThemeHelper.DefaultNightModeChecker; 81 import com.android.managedprovisioning.common.ThemeHelper.DefaultSetupWizardBridge; 82 import com.android.managedprovisioning.common.Utils; 83 import com.android.managedprovisioning.finalization.UserProvisioningStateHelper; 84 import com.android.managedprovisioning.model.ProvisioningParams; 85 86 import com.google.common.collect.Iterables; 87 88 import junit.framework.AssertionFailedError; 89 90 import org.junit.After; 91 import org.junit.AfterClass; 92 import org.junit.Before; 93 import org.junit.BeforeClass; 94 import org.junit.Ignore; 95 import org.junit.Rule; 96 import org.junit.Test; 97 import org.junit.runner.RunWith; 98 import org.mockito.Mock; 99 import org.mockito.hamcrest.MockitoHamcrest; 100 import org.mockito.invocation.Invocation; 101 import org.mockito.junit.MockitoJUnitRunner; 102 103 import java.lang.reflect.Method; 104 import java.util.ArrayList; 105 import java.util.Collection; 106 import java.util.List; 107 108 /** 109 * Unit tests for {@link ProvisioningActivity}. 110 */ 111 @SmallTest 112 @RunWith(MockitoJUnitRunner.class) 113 public class ProvisioningActivityTest { 114 115 private static final String ADMIN_PACKAGE = "com.test.admin"; 116 private static final String TEST_PACKAGE = "com.android.managedprovisioning.tests"; 117 private static final ComponentName ADMIN = new ComponentName(ADMIN_PACKAGE, ".Receiver"); 118 private static final ComponentName TEST_ACTIVITY = new ComponentName(TEST_PACKAGE, 119 EmptyActivity.class.getCanonicalName()); 120 public static final ProvisioningParams PROFILE_OWNER_PARAMS = new ProvisioningParams.Builder() 121 .setProvisioningAction(ACTION_PROVISION_MANAGED_PROFILE) 122 .setDeviceAdminComponentName(ADMIN) 123 .build(); 124 public static final ProvisioningParams DEVICE_OWNER_PARAMS = new ProvisioningParams.Builder() 125 .setProvisioningAction(ACTION_PROVISION_MANAGED_DEVICE) 126 .setDeviceAdminComponentName(ADMIN) 127 .build(); 128 private static final ProvisioningParams FINANCED_DEVICE_PARAMS = new ProvisioningParams 129 .Builder() 130 .setProvisioningAction(ACTION_PROVISION_FINANCED_DEVICE) 131 .setDeviceAdminComponentName(ADMIN) 132 .build(); 133 private static final ProvisioningParams NFC_PARAMS = new ProvisioningParams.Builder() 134 .setProvisioningAction(ACTION_PROVISION_MANAGED_PROFILE) 135 .setDeviceAdminComponentName(ADMIN) 136 .setStartedByTrustedSource(true) 137 .setIsNfc(true) 138 .build(); 139 private static final Intent PROFILE_OWNER_INTENT = new Intent() 140 .putExtra(ProvisioningParams.EXTRA_PROVISIONING_PARAMS, PROFILE_OWNER_PARAMS); 141 private static final Intent DEVICE_OWNER_INTENT = new Intent() 142 .putExtra(ProvisioningParams.EXTRA_PROVISIONING_PARAMS, DEVICE_OWNER_PARAMS); 143 private static final Intent FINANCED_DEVICE_INTENT = new Intent() 144 .putExtra(ProvisioningParams.EXTRA_PROVISIONING_PARAMS, FINANCED_DEVICE_PARAMS); 145 private static final Intent NFC_INTENT = new Intent() 146 .putExtra(ProvisioningParams.EXTRA_PROVISIONING_PARAMS, NFC_PARAMS); 147 private static final int DEFAULT_LOGO_COLOR = Color.rgb(1, 2, 3); 148 private static final int BROADCAST_TIMEOUT = 1000; 149 private static final int WAIT_PROVISIONING_COMPLETE_MILLIS = 60_000; 150 151 private static class CustomIntentsTestRule extends IntentsTestRule<ProvisioningActivity> { 152 private boolean mIsActivityRunning = false; CustomIntentsTestRule()153 private CustomIntentsTestRule() { 154 super(ProvisioningActivity.class, true /* Initial touch mode */, 155 false /* Lazily launch activity */); 156 } 157 158 @Override afterActivityLaunched()159 protected synchronized void afterActivityLaunched() { 160 mIsActivityRunning = true; 161 super.afterActivityLaunched(); 162 } 163 164 @Override afterActivityFinished()165 public synchronized void afterActivityFinished() { 166 // Temp fix for b/37663530 167 if (mIsActivityRunning) { 168 super.afterActivityFinished(); 169 mIsActivityRunning = false; 170 } 171 } 172 } 173 174 @Rule 175 public CustomIntentsTestRule mActivityRule = new CustomIntentsTestRule(); 176 177 @Mock private ProvisioningManager mProvisioningManager; 178 @Mock private PackageManager mPackageManager; 179 @Mock private UserProvisioningStateHelper mUserProvisioningStateHelper; 180 @Mock private PolicyComplianceUtils mPolicyComplianceUtils; 181 @Mock private SettingsFacade mSettingsFacade; 182 183 private Utils mUtils; 184 private static int mRotationLocked; 185 private final ThemeHelper mThemeHelper = 186 new ThemeHelper(new DefaultNightModeChecker(), new DefaultSetupWizardBridge()); 187 188 @BeforeClass setUpClass()189 public static void setUpClass() { 190 // Stop the activity from rotating in order to keep hold of the context 191 Context context = InstrumentationRegistry.getTargetContext(); 192 193 mRotationLocked = Settings.System.getInt(context.getContentResolver(), 194 Settings.System.ACCELEROMETER_ROTATION, 0); 195 Settings.System.putInt(context.getContentResolver(), 196 Settings.System.ACCELEROMETER_ROTATION, 0); 197 } 198 199 @Before setup()200 public void setup() throws RemoteException { 201 mUtils = spy(new Utils()); 202 doNothing().when(mUtils).factoryReset(any(Context.class), anyString()); 203 doReturn(DEFAULT_LOGO_COLOR).when(mUtils).getAccentColor(any()); 204 TestUtils.wakeupDeviceAndPressHome(UiDevice.getInstance(getInstrumentation())); 205 } 206 207 @AfterClass tearDownClass()208 public static void tearDownClass() { 209 // Reset the rotation value back to what it was before the test 210 Context context = InstrumentationRegistry.getTargetContext(); 211 212 Settings.System.putInt(context.getContentResolver(), 213 Settings.System.ACCELEROMETER_ROTATION, mRotationLocked); 214 } 215 216 @Before setUp()217 public void setUp() { 218 TestInstrumentationRunner.registerReplacedActivity(ProvisioningActivity.class, 219 (classLoader, className, intent) -> 220 new ProvisioningActivity( 221 mProvisioningManager, mUtils, mUserProvisioningStateHelper, 222 mPolicyComplianceUtils, mSettingsFacade, mThemeHelper) { 223 @Override 224 public PackageManager getPackageManager() { 225 return mPackageManager; 226 } 227 }); 228 // LogoUtils cached icon globally. Clean-up the cache 229 LogoUtils.cleanUp(InstrumentationRegistry.getTargetContext()); 230 } 231 232 @After tearDown()233 public void tearDown() { 234 TestInstrumentationRunner.unregisterReplacedActivity(ProvisioningActivity.class); 235 } 236 237 @Ignore("b/181323689") 238 @Test testLaunch()239 public void testLaunch() throws NoSuchMethodException { 240 // GIVEN the activity was launched with a profile owner intent 241 launchActivityAndWait(PROFILE_OWNER_INTENT); 242 // THEN the provisioning process should be initiated 243 verify(mProvisioningManager).maybeStartProvisioning(PROFILE_OWNER_PARAMS); 244 245 // THEN the activity should start listening for provisioning updates 246 final Method registerListenerMethod = ProvisioningManager.class 247 .getMethod("registerListener", ProvisioningManagerCallback.class); 248 final int registerListenerInvocations = getNumberOfInvocations(registerListenerMethod); 249 final Method unregisterListenerMethod = ProvisioningManager.class 250 .getMethod("unregisterListener", ProvisioningManagerCallback.class); 251 final int unregisterListenerInvocations = getNumberOfInvocations(unregisterListenerMethod); 252 assertThat(registerListenerInvocations - unregisterListenerInvocations).isEqualTo(1); 253 } 254 getNumberOfInvocations(Method method)255 private int getNumberOfInvocations(Method method) { 256 final Collection<Invocation> invocations = 257 mockingDetails(mProvisioningManager).getInvocations(); 258 return (int) invocations.stream() 259 .filter(invocation -> invocation.getMethod().equals(method)).count(); 260 } 261 262 @Ignore("b/181323689") 263 @Test testSavedInstanceState()264 public void testSavedInstanceState() throws Throwable { 265 // GIVEN the activity was launched with a profile owner intent 266 launchActivityAndWait(PROFILE_OWNER_INTENT); 267 268 // THEN the provisioning process should be initiated 269 verify(mProvisioningManager).maybeStartProvisioning(PROFILE_OWNER_PARAMS); 270 271 // WHEN the activity is recreated with a saved instance state 272 mActivityRule.runOnUiThread(() -> { 273 Bundle bundle = new Bundle(); 274 InstrumentationRegistry.getInstrumentation() 275 .callActivityOnSaveInstanceState(mActivityRule.getActivity(), bundle); 276 mActivityRule.getActivity().recreate(); 277 }); 278 279 // THEN provisioning is attempted to be started again 280 verify(mProvisioningManager).maybeStartProvisioning(PROFILE_OWNER_PARAMS); 281 } 282 283 @Ignore("b/181323689") 284 @Test testPause()285 public void testPause() throws Throwable { 286 // GIVEN the activity was launched with a profile owner intent 287 launchActivityAndWait(PROFILE_OWNER_INTENT); 288 289 reset(mProvisioningManager); 290 291 // WHEN the activity is paused 292 mActivityRule.runOnUiThread(() -> { 293 InstrumentationRegistry.getInstrumentation() 294 .callActivityOnPause(mActivityRule.getActivity()); 295 }); 296 297 // THEN the listener is unregistered 298 // b/130350469 to figure out why onPause/onResume is called one additional time 299 verify(mProvisioningManager).unregisterListener(any(ProvisioningManagerCallback.class)); 300 } 301 302 @Ignore("b/181323689") 303 @Test testCancelDeviceOwner()304 public void testCancelDeviceOwner() throws Throwable { 305 // GIVEN the activity was launched with a device owner intent 306 launchActivityAndWait(DEVICE_OWNER_INTENT); 307 308 // WHEN the user tries to cancel 309 pressBack(); 310 311 // THEN the cancel dialog should be shown 312 onView(withText(R.string.stop_setup_reset_device_question)).check(matches(isDisplayed())); 313 onView(withText(R.string.this_will_reset_take_back_first_screen)) 314 .check(matches(isDisplayed())); 315 316 // WHEN deciding not to cancel 317 onView(withId(android.R.id.button2)) 318 .check(matches(withText(R.string.device_owner_cancel_cancel))) 319 .perform(click()); 320 321 // THEN the activity should not be finished 322 assertFalse(mActivityRule.getActivity().isFinishing()); 323 324 // WHEN the user tries to cancel 325 pressBack(); 326 327 // THEN the cancel dialog should be shown 328 onView(withText(R.string.stop_setup_reset_device_question)).check(matches(isDisplayed())); 329 330 // WHEN deciding to cancel 331 onView(withId(android.R.id.button1)) 332 .check(matches(withText(R.string.reset))) 333 .perform(click()); 334 335 // THEN factory reset should be invoked 336 verify(mUtils, timeout(BROADCAST_TIMEOUT)).factoryReset(any(Context.class), anyString()); 337 } 338 339 @Ignore("b/181323689") 340 @Test testSuccess()341 public void testSuccess() throws Throwable { 342 // GIVEN the activity was launched with a profile owner intent 343 launchActivityAndWait(PROFILE_OWNER_INTENT); 344 345 // WHEN preFinalization is completed 346 mActivityRule.runOnUiThread(() -> mActivityRule.getActivity().preFinalizationCompleted()); 347 348 Thread.sleep(WAIT_PROVISIONING_COMPLETE_MILLIS); 349 350 // Press next button on provisioning complete 351 onView(withText(R.string.next)).perform(click()); 352 353 // THEN the activity should finish 354 onView(withId(R.id.provisioning_progress)); 355 assertTrue(mActivityRule.getActivity().isFinishing()); 356 } 357 358 @Ignore("b/181323689") 359 @Test testSuccess_Nfc()360 public void testSuccess_Nfc() throws Throwable { 361 // GIVEN queryIntentActivities return test_activity 362 ActivityInfo activityInfo = new ActivityInfo(); 363 activityInfo.packageName = TEST_ACTIVITY.getPackageName(); 364 activityInfo.name = TEST_ACTIVITY.getClassName(); 365 activityInfo.permission = permission.BIND_DEVICE_ADMIN; 366 ResolveInfo resolveInfo = new ResolveInfo(); 367 resolveInfo.activityInfo = activityInfo; 368 List<ResolveInfo> resolveInfoList = new ArrayList(); 369 resolveInfoList.add(resolveInfo); 370 when(mPackageManager.queryIntentActivities( 371 MockitoHamcrest.argThat(hasAction(ACTION_STATE_USER_SETUP_COMPLETE)), 372 eq(0))).thenReturn(resolveInfoList); 373 when(mPackageManager.checkPermission(eq(permission.DISPATCH_PROVISIONING_MESSAGE), 374 eq(activityInfo.packageName))).thenReturn(PackageManager.PERMISSION_GRANTED); 375 when(mPolicyComplianceUtils.isPolicyComplianceActivityResolvableForUser( 376 any(), any(), any(), any())).thenReturn(true); 377 378 // GIVEN the activity was launched with a nfc intent 379 launchActivityAndWait(NFC_INTENT); 380 381 // WHEN preFinalization is completed 382 mActivityRule.runOnUiThread(() -> mActivityRule.getActivity().preFinalizationCompleted()); 383 384 Thread.sleep(WAIT_PROVISIONING_COMPLETE_MILLIS); 385 386 // Press next button on provisioning complete 387 onView(withText(R.string.next)).perform(click()); 388 389 // THEN verify starting TEST_ACTIVITY 390 intended(allOf(hasComponent(TEST_ACTIVITY), hasAction(ACTION_STATE_USER_SETUP_COMPLETE))); 391 392 // THEN the activity should finish 393 onView(withId(R.id.provisioning_progress)); 394 assertTrue(mActivityRule.getActivity().isFinishing()); 395 } 396 397 @Ignore("b/181323689") 398 @Test testInitializeUi_profileOwner()399 public void testInitializeUi_profileOwner() throws Throwable { 400 // GIVEN the activity was launched with a profile owner intent 401 launchActivityAndWait(PROFILE_OWNER_INTENT); 402 403 // THEN the profile owner description should be present 404 onView(withId(R.id.provisioning_progress)) 405 .check(matches(withText(R.string.work_profile_provisioning_progress_label))); 406 407 // THEN the animation is shown. 408 onView(withId(R.id.animation)).check(matches(isDisplayed())); 409 } 410 411 @Ignore("b/181323689") 412 @Test testInitializeUi_deviceOwner()413 public void testInitializeUi_deviceOwner() throws Throwable { 414 // GIVEN the activity was launched with a device owner intent 415 launchActivityAndWait(DEVICE_OWNER_INTENT); 416 417 // THEN the description should be empty 418 onView(withId(R.id.provisioning_progress)).check( 419 matches(withText(R.string.fully_managed_device_provisioning_progress_label))); 420 421 // THEN the animation is shown. 422 onView(withId(R.id.animation)).check(matches(isDisplayed())); 423 } 424 425 @Ignore("b/181323689") 426 @Test testInitializeUi_deviceOwnerPermissionGrantOptOut()427 public void testInitializeUi_deviceOwnerPermissionGrantOptOut() throws Throwable { 428 final ProvisioningParams deviceOwnerParams = new ProvisioningParams.Builder() 429 .setProvisioningAction(ACTION_PROVISION_MANAGED_DEVICE) 430 .setDeviceAdminComponentName(ADMIN) 431 .setDeviceOwnerPermissionGrantOptOut(true) 432 .build(); 433 434 final Intent deviceOwnerIntent = new Intent() 435 .putExtra(ProvisioningParams.EXTRA_PROVISIONING_PARAMS, deviceOwnerParams); 436 437 // GIVEN the activity was launched with a device owner intent 438 launchActivityAndWait(deviceOwnerIntent); 439 440 // THEN the description should be empty 441 onView(withId(R.id.provisioning_progress)).check( 442 matches(withText(R.string.fully_managed_device_provisioning_progress_label))); 443 444 // THEN the animation is shown. 445 onView(withId(R.id.animation)).check(matches(isDisplayed())); 446 waitForFullyManagedDeviceHeader(); 447 448 onView(withId(R.id.sud_layout_subtitle)).check(matches( 449 withText(R.string.fully_managed_device_provisioning_step_2_subheader))); 450 onView(withId(R.id.item1)).check(matches(not(isDisplayed()))); 451 onView(withId(R.id.item2)).check(matches(not(isDisplayed()))); 452 } 453 454 @Ignore("b/181323689") 455 @Test testInitializeUi_deviceOwnerDefault()456 public void testInitializeUi_deviceOwnerDefault() throws Throwable { 457 // GIVEN the activity was launched with a device owner intent 458 launchActivityAndWait(DEVICE_OWNER_INTENT); 459 460 // THEN the description should be empty 461 onView(withId(R.id.provisioning_progress)).check( 462 matches(withText(R.string.fully_managed_device_provisioning_progress_label))); 463 464 // THEN the animation is shown. 465 onView(withId(R.id.animation)).check(matches(isDisplayed())); 466 waitForFullyManagedDeviceHeader(); 467 468 onView(allOf(withId(R.id.sud_items_title), withParent(withId(R.id.item1)))) 469 .check(matches( 470 withText(R.string.fully_managed_device_provisioning_permissions_header))); 471 onView(allOf(withId(R.id.sud_items_summary), withParent(withId(R.id.item1)))) 472 .check(matches(withText( 473 R.string.fully_managed_device_provisioning_permissions_subheader))); 474 onView(allOf(withId(R.id.sud_items_title), withParent(withId(R.id.item2)))) 475 .check(matches(withText( 476 R.string.fully_managed_device_provisioning_permissions_secondary_header))); 477 onView(allOf(withId(R.id.sud_items_summary), withParent(withId(R.id.item2)))) 478 .check(matches(withText(R.string 479 .fully_managed_device_provisioning_permissions_secondary_subheader))); 480 } 481 482 @Ignore("b/181323689") 483 @Test testInitializeUi_deviceOwnerCanAbort()484 public void testInitializeUi_deviceOwnerCanAbort() throws Throwable { 485 // GIVEN the activity was launched with a device owner intent 486 launchActivityAndWait(DEVICE_OWNER_INTENT); 487 488 // THEN the description should be empty 489 onView(withId(R.id.provisioning_progress)).check( 490 matches(withText(R.string.fully_managed_device_provisioning_progress_label))); 491 492 // THEN the animation is shown. 493 onView(withId(R.id.animation)).check(matches(isDisplayed())); 494 waitForFullyManagedDeviceHeader(); 495 // WHEN preFinalization is completed 496 mActivityRule.runOnUiThread(() -> mActivityRule.getActivity().preFinalizationCompleted()); 497 // THEN the cancel button should be available. 498 waitForCancelSetupButtonAndClickIt(); 499 500 // Check 501 Intent receivedIntent = Iterables.getOnlyElement(Intents.getIntents()); 502 assertThat(receivedIntent).isNotNull(); 503 assertThat(receivedIntent.getComponent()).isEqualTo( 504 new ComponentName(InstrumentationRegistry.getTargetContext(), 505 ResetAndReturnDeviceActivity.class)); 506 assertThat(receivedIntent.hasExtra(ProvisioningParams.EXTRA_PROVISIONING_PARAMS)).isTrue(); 507 assertThat(receivedIntent.hasExtra("wizardBundle")).isTrue(); 508 } 509 510 //TODO(b/180399632): Replace this wait with callbacks or another mechanism where the 511 //activity-under-test is more collaborative with the testing infrastructure to indicate 512 //its state. waitForCancelSetupButtonAndClickIt()513 private void waitForCancelSetupButtonAndClickIt() throws InterruptedException { 514 final int cancelButtonId = 3; 515 int numAttempts = 0; 516 while (numAttempts < 40) { 517 try { 518 onView(withId(cancelButtonId)) 519 .check(matches( 520 withText(R.string.fully_managed_device_cancel_setup_button))); 521 onView(withId(cancelButtonId)).check(matches(isDisplayed())); 522 break; 523 } catch (AssertionFailedError e) { 524 numAttempts++; 525 } 526 Thread.sleep(500); 527 } 528 529 // Click the cancel button. 530 onView(withId(cancelButtonId)) 531 .check(matches(withText(R.string.fully_managed_device_cancel_setup_button))) 532 .perform(click()); 533 } 534 535 @Ignore("b/181323689") 536 @Test testInitializeUi_financedDevice()537 public void testInitializeUi_financedDevice() throws Throwable { 538 // GIVEN the activity was launched with a financed device intent 539 launchActivityAndWait(FINANCED_DEVICE_INTENT); 540 541 // THEN the header will be set 542 onView(withId(R.id.suc_layout_title)).check(matches(withText(R.string.just_a_sec))); 543 544 // THEN the icon will be invisible 545 onView(withId(R.id.sud_layout_icon)).check(matches(not(isDisplayed()))); 546 547 // THEN the animation is shown. 548 onView(withId(R.id.animation)).check(matches(isDisplayed())); 549 } 550 launchActivityAndWait(Intent intent)551 private void launchActivityAndWait(Intent intent) { 552 mActivityRule.launchActivity(intent); 553 onView(withId(R.id.setup_wizard_layout)); 554 } 555 556 // TODO(b/180399632): Utilize a callback, IdlingResource, etc. waitForFullyManagedDeviceHeader()557 private void waitForFullyManagedDeviceHeader() throws InterruptedException { 558 int numAttempts = 0; 559 while (numAttempts < 40) { 560 try { 561 onView(withId(R.id.sud_layout_subtitle)).check(matches( 562 withText(R.string.fully_managed_device_provisioning_step_2_subheader))); 563 break; 564 } catch (AssertionFailedError e) { 565 numAttempts++; 566 } 567 Thread.sleep(500); 568 } 569 } 570 } 571