Home | History | Annotate | Download | only in uiflows
      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