1 /* 2 * Copyright (C) 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 package com.android.managedprovisioning.uiflows; 17 18 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE; 19 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE; 20 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE; 21 import static android.nfc.NfcAdapter.ACTION_NDEF_DISCOVERED; 22 import static com.android.managedprovisioning.common.Globals.ACTION_RESUME_PROVISIONING; 23 import static org.mockito.Mockito.any; 24 import static org.mockito.Mockito.anyInt; 25 import static org.mockito.Mockito.anyString; 26 import static org.mockito.Mockito.eq; 27 import static org.mockito.Mockito.never; 28 import static org.mockito.Mockito.verify; 29 import static org.mockito.Mockito.verifyNoMoreInteractions; 30 import static org.mockito.Mockito.verifyZeroInteractions; 31 import static org.mockito.Mockito.when; 32 33 import android.app.ActivityManager; 34 import android.app.KeyguardManager; 35 import android.app.admin.DevicePolicyManager; 36 import android.content.ComponentName; 37 import android.content.Context; 38 import android.content.Intent; 39 import android.content.pm.PackageManager; 40 import android.os.UserManager; 41 import android.service.persistentdata.PersistentDataBlockManager; 42 import android.test.AndroidTestCase; 43 import android.test.suitebuilder.annotation.SmallTest; 44 import android.text.TextUtils; 45 46 import com.android.managedprovisioning.R; 47 import com.android.managedprovisioning.common.IllegalProvisioningArgumentException; 48 import com.android.managedprovisioning.common.Utils; 49 import com.android.managedprovisioning.model.ProvisioningParams; 50 import com.android.managedprovisioning.model.WifiInfo; 51 import com.android.managedprovisioning.parser.MessageParser; 52 53 import org.mockito.Mock; 54 import org.mockito.MockitoAnnotations; 55 56 @SmallTest 57 public class PreProvisioningControllerTest extends AndroidTestCase { 58 private static final String TEST_MDM_PACKAGE = "com.test.mdm"; 59 private static final ComponentName TEST_MDM_COMPONENT_NAME = new ComponentName(TEST_MDM_PACKAGE, 60 "com.test.mdm.DeviceAdmin"); 61 private static final String TEST_BOGUS_PACKAGE = "com.test.bogus"; 62 private static final String TEST_WIFI_SSID = "TestNet"; 63 private static final String MP_PACKAGE_NAME = "com.android.managedprovisioning"; 64 private static final int TEST_USER_ID = 10; 65 66 @Mock private Context mContext; 67 @Mock private DevicePolicyManager mDevicePolicyManager; 68 @Mock private UserManager mUserManager; 69 @Mock private PackageManager mPackageManager; 70 @Mock private ActivityManager mActivityManager; 71 @Mock private KeyguardManager mKeyguardManager; 72 @Mock private PersistentDataBlockManager mPdbManager; 73 @Mock private PreProvisioningController.Ui mUi; 74 @Mock private MessageParser mMessageParser; 75 @Mock private Utils mUtils; 76 @Mock private Intent mIntent; 77 @Mock private EncryptionController mEncryptionController; 78 79 private ProvisioningParams mParams; 80 81 private PreProvisioningController mController; 82 83 @Override 84 public void setUp() { 85 // this is necessary for mockito to work 86 System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString()); 87 88 MockitoAnnotations.initMocks(this); 89 90 when(mContext.getSystemService(Context.DEVICE_POLICY_SERVICE)) 91 .thenReturn(mDevicePolicyManager); 92 when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager); 93 when(mContext.getPackageManager()).thenReturn(mPackageManager); 94 when(mContext.getSystemService(Context.ACTIVITY_SERVICE)).thenReturn(mActivityManager); 95 when(mContext.getSystemService(Context.KEYGUARD_SERVICE)).thenReturn(mKeyguardManager); 96 when(mContext.getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE)) 97 .thenReturn(mPdbManager); 98 when(mContext.getPackageName()).thenReturn(MP_PACKAGE_NAME); 99 100 when(mUserManager.getUserHandle()).thenReturn(TEST_USER_ID); 101 102 when(mUtils.isFrpSupported(mContext)).thenReturn(true); 103 when(mUtils.isSplitSystemUser()).thenReturn(false); 104 when(mUtils.isEncryptionRequired()).thenReturn(false); 105 when(mUtils.currentLauncherSupportsManagedProfiles(mContext)).thenReturn(true); 106 when(mUtils.alreadyHasManagedProfile(mContext)).thenReturn(-1); 107 108 when(mKeyguardManager.inKeyguardRestrictedInputMode()).thenReturn(false); 109 when(mDevicePolicyManager.getStorageEncryptionStatus()) 110 .thenReturn(DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE); 111 112 mController = new PreProvisioningController(mContext, mUi, mMessageParser, mUtils, 113 mEncryptionController); 114 } 115 116 public void testManagedProfile() throws Exception { 117 // GIVEN an intent to provision a managed profile 118 prepareMocksForManagedProfileIntent(false); 119 // WHEN initiating provisioning 120 mController.initiateProvisioning(mIntent, TEST_MDM_PACKAGE); 121 // THEN the UI elements should be updated accordingly 122 verifyInitiateProfileOwnerUi(); 123 // WHEN the user clicks next 124 mController.afterNavigateNext(); 125 // THEN show a user consent dialog 126 verify(mUi).showUserConsentDialog(mParams, true); 127 // WHEN the user consents 128 mController.continueProvisioningAfterUserConsent(); 129 // THEN start profile provisioning 130 verify(mUi).startProfileOwnerProvisioning(mParams); 131 verify(mEncryptionController).cancelEncryptionReminder(); 132 verifyNoMoreInteractions(mUi); 133 } 134 135 public void testManagedProfile_provisioningNotAllowed() throws Exception { 136 // GIVEN an intent to provision a managed profile, but provisioning mode is not allowed 137 prepareMocksForManagedProfileIntent(false); 138 when(mDevicePolicyManager.isProvisioningAllowed(ACTION_PROVISION_MANAGED_PROFILE)) 139 .thenReturn(false); 140 // WHEN initiating provisioning 141 mController.initiateProvisioning(mIntent, TEST_MDM_PACKAGE); 142 // THEN show an error dialog 143 verify(mUi).showErrorAndClose(anyInt(), anyString()); 144 verifyNoMoreInteractions(mUi); 145 } 146 147 public void testManagedProfile_nullCallingPackage() throws Exception { 148 // GIVEN a device that is not currently encrypted 149 prepareMocksForManagedProfileIntent(false); 150 try { 151 // WHEN initiating provisioning 152 mController.initiateProvisioning(mIntent, null); 153 fail("Expected NullPointerException not thrown"); 154 } catch (NullPointerException ne) { 155 // THEN a NullPointerException is thrown 156 } 157 // THEN no user interaction occurs 158 verifyZeroInteractions(mUi); 159 } 160 161 public void testManagedProfile_withEncryption() throws Exception { 162 // GIVEN a device that is not currently encrypted 163 prepareMocksForManagedProfileIntent(false); 164 when(mUtils.isEncryptionRequired()).thenReturn(true); 165 // WHEN initiating managed profile provisioning 166 mController.initiateProvisioning(mIntent, TEST_MDM_PACKAGE); 167 // THEN the UI elements should be updated accordingly 168 verifyInitiateProfileOwnerUi(); 169 // WHEN the user clicks next 170 mController.afterNavigateNext(); 171 // THEN show encryption screen 172 verify(mUi).requestEncryption(mParams); 173 verifyNoMoreInteractions(mUi); 174 } 175 176 public void testManagedProfile_afterEncryption() throws Exception { 177 // GIVEN managed profile provisioning continues after successful encryption. In this case 178 // we don't set the startedByTrustedSource flag. 179 prepareMocksForAfterEncryption(ACTION_PROVISION_MANAGED_PROFILE, false); 180 // WHEN initiating with a continuation intent 181 mController.initiateProvisioning(mIntent, MP_PACKAGE_NAME); 182 // THEN the UI elements should be updated accordingly 183 verifyInitiateProfileOwnerUi(); 184 // WHEN the user clicks next 185 mController.afterNavigateNext(); 186 // THEN show a user consent dialog 187 verify(mUi).showUserConsentDialog(mParams, true); 188 // WHEN the user consents 189 mController.continueProvisioningAfterUserConsent(); 190 // THEN start profile provisioning 191 verify(mUi).startProfileOwnerProvisioning(mParams); 192 verify(mEncryptionController).cancelEncryptionReminder(); 193 verifyNoMoreInteractions(mUi); 194 } 195 196 public void testManagedProfile_withExistingProfile() throws Exception { 197 // GIVEN a managed profile currently exist on the device 198 prepareMocksForManagedProfileIntent(false); 199 when(mUtils.alreadyHasManagedProfile(mContext)).thenReturn(TEST_USER_ID); 200 // WHEN initiating managed profile provisioning 201 mController.initiateProvisioning(mIntent, TEST_MDM_PACKAGE); 202 // THEN the UI elements should be updated accordingly and a dialog to remove the existing 203 // profile should be shown 204 verifyInitiateProfileOwnerUi(); 205 verify(mUi).showDeleteManagedProfileDialog(any(ComponentName.class), 206 anyString(), eq(TEST_USER_ID)); 207 // WHEN the user clicks next 208 mController.afterNavigateNext(); 209 // THEN show a user consent dialog 210 verify(mUi).showUserConsentDialog(mParams, true); 211 // WHEN the user consents 212 mController.continueProvisioningAfterUserConsent(); 213 // THEN start profile provisioning 214 verify(mUi).startProfileOwnerProvisioning(mParams); 215 verify(mEncryptionController).cancelEncryptionReminder(); 216 verifyNoMoreInteractions(mUi); 217 } 218 219 public void testManagedProfile_badLauncher() throws Exception { 220 // GIVEN that the current launcher does not support managed profiles 221 prepareMocksForManagedProfileIntent(false); 222 when(mUtils.currentLauncherSupportsManagedProfiles(mContext)).thenReturn(false); 223 // WHEN initiating managed profile provisioning 224 mController.initiateProvisioning(mIntent, TEST_MDM_PACKAGE); 225 // THEN the UI elements should be updated accordingly 226 verifyInitiateProfileOwnerUi(); 227 // WHEN the user clicks next 228 mController.afterNavigateNext(); 229 // THEN show a user consent dialog 230 verify(mUi).showUserConsentDialog(mParams, true); 231 // WHEN the user consents 232 mController.continueProvisioningAfterUserConsent(); 233 // THEN show a dialog indicating that the current launcher is invalid 234 verify(mUi).showCurrentLauncherInvalid(); 235 verifyNoMoreInteractions(mUi); 236 } 237 238 public void testManagedProfile_wrongPackage() throws Exception { 239 // GIVEN that the provisioning intent tries to set a package different from the caller 240 // as owner of the profile 241 prepareMocksForManagedProfileIntent(false); 242 // WHEN initiating managed profile provisioning 243 mController.initiateProvisioning(mIntent, TEST_BOGUS_PACKAGE); 244 // THEN show an error dialog and do not continue 245 verify(mUi).showErrorAndClose(eq(R.string.device_owner_error_general), anyString()); 246 verifyNoMoreInteractions(mUi); 247 } 248 249 public void testManagedProfile_frp() throws Exception { 250 // GIVEN managed profile provisioning is invoked from SUW with FRP active 251 prepareMocksForManagedProfileIntent(false); 252 when(mUtils.isDeviceProvisioned(mContext)).thenReturn(false); 253 // setting the data block size to any number greater than 0 should invoke FRP. 254 when(mPdbManager.getDataBlockSize()).thenReturn(4); 255 // WHEN initiating managed profile provisioning 256 mController.initiateProvisioning(mIntent, TEST_MDM_PACKAGE); 257 // THEN show an error dialog and do not continue 258 verify(mUi).showErrorAndClose(eq(R.string.device_owner_error_frp), anyString()); 259 verifyNoMoreInteractions(mUi); 260 } 261 262 public void testManagedProfile_skipEncryption() throws Exception { 263 // GIVEN an intent to provision a managed profile with skip encryption 264 prepareMocksForManagedProfileIntent(true); 265 when(mUtils.isEncryptionRequired()).thenReturn(true); 266 // WHEN initiating provisioning 267 mController.initiateProvisioning(mIntent, TEST_MDM_PACKAGE); 268 // THEN the UI elements should be updated accordingly 269 verifyInitiateProfileOwnerUi(); 270 // WHEN the user clicks next 271 mController.afterNavigateNext(); 272 // THEN show a user consent dialog 273 verify(mUi).showUserConsentDialog(mParams, true); 274 // WHEN the user consents 275 mController.continueProvisioningAfterUserConsent(); 276 // THEN start profile provisioning 277 verify(mUi).startProfileOwnerProvisioning(mParams); 278 verify(mUi, never()).requestEncryption(any(ProvisioningParams.class)); 279 verify(mEncryptionController).cancelEncryptionReminder(); 280 verifyNoMoreInteractions(mUi); 281 } 282 283 public void testManagedProfile_encryptionNotSupported() throws Exception { 284 // GIVEN an intent to provision a managed profile on an unencrypted device that does not 285 // support encryption 286 prepareMocksForManagedProfileIntent(false); 287 when(mUtils.isEncryptionRequired()).thenReturn(true); 288 when(mDevicePolicyManager.getStorageEncryptionStatus()) 289 .thenReturn(DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED); 290 // WHEN initiating provisioning 291 mController.initiateProvisioning(mIntent, TEST_MDM_PACKAGE); 292 // THEN the UI elements should be updated accordingly 293 verifyInitiateProfileOwnerUi(); 294 // WHEN the user clicks next 295 mController.afterNavigateNext(); 296 // THEN show an error indicating that this device does not support encryption 297 verify(mUi).showErrorAndClose(eq(R.string.preprovisioning_error_encryption_not_supported), 298 anyString()); 299 verifyNoMoreInteractions(mUi); 300 } 301 302 public void testNfc() throws Exception { 303 // GIVEN provisioning was started via an NFC tap and device is already encrypted 304 prepareMocksForNfcIntent(ACTION_PROVISION_MANAGED_DEVICE, false); 305 // WHEN initiating NFC provisioning 306 mController.initiateProvisioning(mIntent, null); 307 // THEN show a user consent dialog 308 verify(mUi).showUserConsentDialog(mParams, false); 309 // WHEN the user consents 310 mController.continueProvisioningAfterUserConsent(); 311 // THEN start device owner provisioning 312 verify(mUi).startDeviceOwnerProvisioning(TEST_USER_ID, mParams); 313 verify(mEncryptionController).cancelEncryptionReminder(); 314 verifyNoMoreInteractions(mUi); 315 } 316 317 public void testNfc_skipEncryption() throws Exception { 318 // GIVEN provisioning was started via an NFC tap with encryption skipped 319 prepareMocksForNfcIntent(ACTION_PROVISION_MANAGED_DEVICE, true); 320 when(mUtils.isEncryptionRequired()).thenReturn(true); 321 // WHEN initiating NFC provisioning 322 mController.initiateProvisioning(mIntent, null); 323 // THEN show a user consent dialog 324 verify(mUi).showUserConsentDialog(mParams, false); 325 // WHEN the user consents 326 mController.continueProvisioningAfterUserConsent(); 327 // THEN start device owner provisioning 328 verify(mUi).startDeviceOwnerProvisioning(TEST_USER_ID, mParams); 329 verify(mUi, never()).requestEncryption(any(ProvisioningParams.class)); 330 verify(mEncryptionController).cancelEncryptionReminder(); 331 verifyNoMoreInteractions(mUi); 332 } 333 334 public void testNfc_withEncryption() throws Exception { 335 // GIVEN provisioning was started via an NFC tap with encryption necessary 336 prepareMocksForNfcIntent(ACTION_PROVISION_MANAGED_DEVICE, false); 337 when(mUtils.isEncryptionRequired()).thenReturn(true); 338 // WHEN initiating NFC provisioning 339 mController.initiateProvisioning(mIntent, null); 340 // THEN show encryption screen 341 verify(mUi).requestEncryption(mParams); 342 verifyNoMoreInteractions(mUi); 343 } 344 345 public void testNfc_afterEncryption() throws Exception { 346 // GIVEN provisioning was started via an NFC tap and we have gone through encryption 347 // in this case the device gets resumed with the DO intent and startedByTrustedSource flag 348 // set 349 prepareMocksForAfterEncryption(ACTION_PROVISION_MANAGED_DEVICE, true); 350 // WHEN continuing NFC provisioning after encryption 351 mController.initiateProvisioning(mIntent, null); 352 // THEN show a user consent dialog 353 verify(mUi).showUserConsentDialog(mParams, false); 354 // WHEN the user consents 355 mController.continueProvisioningAfterUserConsent(); 356 // THEN start device owner provisioning 357 verify(mUi).startDeviceOwnerProvisioning(TEST_USER_ID, mParams); 358 verifyNoMoreInteractions(mUi); 359 } 360 361 public void testNfc_frp() throws Exception { 362 // GIVEN provisioning was started via an NFC tap, but the device is locked with FRP 363 prepareMocksForNfcIntent(ACTION_PROVISION_MANAGED_DEVICE, false); 364 // setting the data block size to any number greater than 0 should invoke FRP. 365 when(mPdbManager.getDataBlockSize()).thenReturn(4); 366 // WHEN initiating NFC provisioning 367 mController.initiateProvisioning(mIntent, null); 368 // THEN show an error dialog 369 verify(mUi).showErrorAndClose(eq(R.string.device_owner_error_frp), anyString()); 370 verifyNoMoreInteractions(mUi); 371 } 372 373 public void testNfc_encryptionNotSupported() throws Exception { 374 // GIVEN provisioning was started via an NFC tap, the device is not encrypted and encryption 375 // is not supported on the device 376 prepareMocksForNfcIntent(ACTION_PROVISION_MANAGED_DEVICE, false); 377 when(mUtils.isEncryptionRequired()).thenReturn(true); 378 when(mDevicePolicyManager.getStorageEncryptionStatus()) 379 .thenReturn(DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED); 380 // WHEN initiating NFC provisioning 381 mController.initiateProvisioning(mIntent, null); 382 // THEN show an error dialog 383 verify(mUi).showErrorAndClose(eq(R.string.preprovisioning_error_encryption_not_supported), 384 anyString()); 385 verifyNoMoreInteractions(mUi); 386 } 387 388 public void testQr() throws Exception { 389 // GIVEN provisioning was started via a QR code and device is already encrypted 390 prepareMocksForQrIntent(ACTION_PROVISION_MANAGED_DEVICE, false); 391 // WHEN initiating QR provisioning 392 mController.initiateProvisioning(mIntent, null); 393 // THEN show a user consent dialog 394 verify(mUi).showUserConsentDialog(mParams, false); 395 // WHEN the user consents 396 mController.continueProvisioningAfterUserConsent(); 397 // THEN start device owner provisioning 398 verify(mUi).startDeviceOwnerProvisioning(TEST_USER_ID, mParams); 399 verifyNoMoreInteractions(mUi); 400 } 401 402 public void testQr_skipEncryption() throws Exception { 403 // GIVEN provisioning was started via a QR code with encryption skipped 404 prepareMocksForQrIntent(ACTION_PROVISION_MANAGED_DEVICE, true); 405 when(mUtils.isEncryptionRequired()).thenReturn(true); 406 // WHEN initiating QR provisioning 407 mController.initiateProvisioning(mIntent, null); 408 // THEN show a user consent dialog 409 verify(mUi).showUserConsentDialog(mParams, false); 410 // WHEN the user consents 411 mController.continueProvisioningAfterUserConsent(); 412 // THEN start device owner provisioning 413 verify(mUi).startDeviceOwnerProvisioning(TEST_USER_ID, mParams); 414 verify(mUi, never()).requestEncryption(any(ProvisioningParams.class)); 415 verifyNoMoreInteractions(mUi); 416 } 417 418 public void testQr_withEncryption() throws Exception { 419 // GIVEN provisioning was started via a QR code with encryption necessary 420 prepareMocksForQrIntent(ACTION_PROVISION_MANAGED_DEVICE, false); 421 when(mUtils.isEncryptionRequired()).thenReturn(true); 422 // WHEN initiating QR provisioning 423 mController.initiateProvisioning(mIntent, null); 424 // THEN show encryption screen 425 verify(mUi).requestEncryption(mParams); 426 verifyNoMoreInteractions(mUi); 427 } 428 429 public void testQr_frp() throws Exception { 430 // GIVEN provisioning was started via a QR code, but the device is locked with FRP 431 prepareMocksForQrIntent(ACTION_PROVISION_MANAGED_DEVICE, false); 432 // setting the data block size to any number greater than 0 should invoke FRP. 433 when(mPdbManager.getDataBlockSize()).thenReturn(4); 434 // WHEN initiating QR provisioning 435 mController.initiateProvisioning(mIntent, null); 436 // THEN show an error dialog 437 verify(mUi).showErrorAndClose(eq(R.string.device_owner_error_frp), anyString()); 438 verifyNoMoreInteractions(mUi); 439 } 440 441 public void testDeviceOwner() throws Exception { 442 // GIVEN device owner provisioning was started and device is already encrypted 443 prepareMocksForDoIntent(true); 444 // WHEN initiating provisioning 445 mController.initiateProvisioning(mIntent, TEST_MDM_PACKAGE); 446 // THEN the UI elements should be updated accordingly 447 verifyInitiateDeviceOwnerUi(); 448 // WHEN the user clicks next 449 mController.afterNavigateNext(); 450 // THEN show a user consent dialog 451 verify(mUi).showUserConsentDialog(mParams, false); 452 // WHEN the user consents 453 mController.continueProvisioningAfterUserConsent(); 454 // THEN start device owner provisioning 455 verify(mUi).startDeviceOwnerProvisioning(TEST_USER_ID, mParams); 456 verify(mEncryptionController).cancelEncryptionReminder(); 457 verifyNoMoreInteractions(mUi); 458 } 459 460 public void testDeviceOwner_skipEncryption() throws Exception { 461 // GIVEN device owner provisioning was started with skip encryption flag 462 prepareMocksForDoIntent(true); 463 when(mUtils.isEncryptionRequired()).thenReturn(true); 464 // WHEN initiating provisioning 465 mController.initiateProvisioning(mIntent, TEST_MDM_PACKAGE); 466 // THEN the UI elements should be updated accordingly 467 verifyInitiateDeviceOwnerUi(); 468 // WHEN the user clicks next 469 mController.afterNavigateNext(); 470 // THEN show a user consent dialog 471 verify(mUi).showUserConsentDialog(mParams, false); 472 // WHEN the user consents 473 mController.continueProvisioningAfterUserConsent(); 474 // THEN start device owner provisioning 475 verify(mUi).startDeviceOwnerProvisioning(TEST_USER_ID, mParams); 476 verify(mUi, never()).requestEncryption(any(ProvisioningParams.class)); 477 verify(mEncryptionController).cancelEncryptionReminder(); 478 verifyNoMoreInteractions(mUi); 479 } 480 481 // TODO: There is a difference in behaviour here between the managed profile and the device 482 // owner case: In managed profile case, we invoke encryption after user clicks next, but in 483 // device owner mode we invoke it straight away. Also in theory no need to update 484 // the UI elements if we're moving away from this activity straight away. 485 public void testDeviceOwner_withEncryption() throws Exception { 486 // GIVEN device owner provisioning is started with encryption needed 487 prepareMocksForDoIntent(false); 488 when(mUtils.isEncryptionRequired()).thenReturn(true); 489 // WHEN initiating provisioning 490 mController.initiateProvisioning(mIntent, TEST_MDM_PACKAGE); 491 // THEN update the UI elements and show encryption screen 492 verifyInitiateDeviceOwnerUi(); 493 verify(mUi).requestEncryption(mParams); 494 verifyNoMoreInteractions(mUi); 495 } 496 497 public void testDeviceOwner_afterEncryption() throws Exception { 498 // GIVEN device owner provisioning is continued after encryption. In this case we do not set 499 // the startedByTrustedSource flag. 500 prepareMocksForAfterEncryption(ACTION_PROVISION_MANAGED_DEVICE, false); 501 // WHEN provisioning is continued 502 mController.initiateProvisioning(mIntent, null); 503 // THEN the UI elements should be updated accordingly 504 verifyInitiateDeviceOwnerUi(); 505 // WHEN the user clicks next 506 mController.afterNavigateNext(); 507 // THEN show a user consent dialog 508 verify(mUi).showUserConsentDialog(mParams, false); 509 // WHEN the user consents 510 mController.continueProvisioningAfterUserConsent(); 511 // THEN start device owner provisioning 512 verify(mUi).startDeviceOwnerProvisioning(TEST_USER_ID, mParams); 513 verify(mEncryptionController).cancelEncryptionReminder(); 514 verifyNoMoreInteractions(mUi); 515 } 516 517 public void testDeviceOwner_frp() throws Exception { 518 // GIVEN device owner provisioning is invoked with FRP active 519 prepareMocksForDoIntent(false); 520 // setting the data block size to any number greater than 0 should invoke FRP. 521 when(mPdbManager.getDataBlockSize()).thenReturn(4); 522 // WHEN initiating provisioning 523 mController.initiateProvisioning(mIntent, TEST_MDM_PACKAGE); 524 // THEN show an error dialog 525 verify(mUi).showErrorAndClose(eq(R.string.device_owner_error_frp), anyString()); 526 verifyNoMoreInteractions(mUi); 527 } 528 529 private void prepareMocksForManagedProfileIntent(boolean skipEncryption) throws Exception { 530 final String action = ACTION_PROVISION_MANAGED_PROFILE; 531 when(mIntent.getAction()).thenReturn(action); 532 when(mUtils.findDeviceAdmin(TEST_MDM_PACKAGE, null, mContext)) 533 .thenReturn(TEST_MDM_COMPONENT_NAME); 534 when(mUtils.isDeviceProvisioned(mContext)).thenReturn(true); 535 when(mDevicePolicyManager.isProvisioningAllowed(action)).thenReturn(true); 536 when(mMessageParser.parse(mIntent, mContext)).thenReturn( 537 createParams(false, skipEncryption, null, action, TEST_MDM_PACKAGE)); 538 } 539 540 private void prepareMocksForNfcIntent(String action, boolean skipEncryption) throws Exception { 541 when(mIntent.getAction()).thenReturn(ACTION_NDEF_DISCOVERED); 542 when(mDevicePolicyManager.isProvisioningAllowed(action)).thenReturn(true); 543 when(mMessageParser.parse(mIntent, mContext)).thenReturn( 544 createParams(true, skipEncryption, TEST_WIFI_SSID, action, TEST_MDM_PACKAGE)); 545 } 546 547 private void prepareMocksForQrIntent(String action, boolean skipEncryption) throws Exception { 548 when(mIntent.getAction()) 549 .thenReturn(ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE); 550 when(mDevicePolicyManager.isProvisioningAllowed(action)).thenReturn(true); 551 when(mMessageParser.parse(mIntent, mContext)).thenReturn( 552 createParams(true, skipEncryption, TEST_WIFI_SSID, action, TEST_MDM_PACKAGE)); 553 } 554 555 private void prepareMocksForDoIntent(boolean skipEncryption) throws Exception { 556 final String action = ACTION_PROVISION_MANAGED_DEVICE; 557 when(mIntent.getAction()).thenReturn(action); 558 when(mDevicePolicyManager.isProvisioningAllowed(action)).thenReturn(true); 559 when(mMessageParser.parse(mIntent, mContext)).thenReturn( 560 createParams(false, skipEncryption, TEST_WIFI_SSID, action, TEST_MDM_PACKAGE)); 561 } 562 563 private void prepareMocksForAfterEncryption(String action, boolean startedByTrustedSource) 564 throws Exception { 565 when(mIntent.getAction()).thenReturn(ACTION_RESUME_PROVISIONING); 566 when(mDevicePolicyManager.isProvisioningAllowed(action)).thenReturn(true); 567 when(mMessageParser.parse(mIntent, mContext)).thenReturn( 568 createParams( 569 startedByTrustedSource, false, TEST_WIFI_SSID, action, TEST_MDM_PACKAGE)); 570 } 571 572 private ProvisioningParams createParams(boolean startedByTrustedSource, boolean skipEncryption, 573 String wifiSsid, String action, String packageName) { 574 ProvisioningParams.Builder builder = ProvisioningParams.Builder.builder() 575 .setStartedByTrustedSource(startedByTrustedSource) 576 .setSkipEncryption(skipEncryption) 577 .setProvisioningAction(action) 578 .setDeviceAdminPackageName(packageName); 579 if (!TextUtils.isEmpty(wifiSsid)) { 580 builder.setWifiInfo(WifiInfo.Builder.builder().setSsid(wifiSsid).build()); 581 } 582 return mParams = builder.build(); 583 } 584 585 private void verifyInitiateProfileOwnerUi() { 586 verify(mUi).initiateUi( 587 R.string.setup_work_profile, 588 R.string.setup_profile_start_setup, 589 R.string.company_controls_workspace, 590 R.string.the_following_is_your_mdm, 591 mParams); 592 } 593 594 private void verifyInitiateDeviceOwnerUi() { 595 verify(mUi).initiateUi( 596 R.string.setup_work_device, 597 R.string.setup_device_start_setup, 598 R.string.company_controls_device, 599 R.string.the_following_is_your_mdm_for_device, 600 mParams); 601 } 602 } 603