• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
setUp()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 
testManagedProfile()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 
testManagedProfile_provisioningNotAllowed()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 
testManagedProfile_nullCallingPackage()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 
testManagedProfile_withEncryption()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 
testManagedProfile_afterEncryption()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 
testManagedProfile_withExistingProfile()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 
testManagedProfile_badLauncher()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 
testManagedProfile_wrongPackage()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 
testManagedProfile_frp()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 
testManagedProfile_skipEncryption()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 
testManagedProfile_encryptionNotSupported()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 
testNfc()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 
testNfc_skipEncryption()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 
testNfc_withEncryption()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 
testNfc_afterEncryption()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 
testNfc_frp()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 
testNfc_encryptionNotSupported()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 
testQr()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 
testQr_skipEncryption()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 
testQr_withEncryption()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 
testQr_frp()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 
testDeviceOwner()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 
testDeviceOwner_skipEncryption()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.
testDeviceOwner_withEncryption()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 
testDeviceOwner_afterEncryption()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 
testDeviceOwner_frp()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 
prepareMocksForManagedProfileIntent(boolean skipEncryption)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 
prepareMocksForNfcIntent(String action, boolean skipEncryption)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 
prepareMocksForQrIntent(String action, boolean skipEncryption)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 
prepareMocksForDoIntent(boolean skipEncryption)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 
prepareMocksForAfterEncryption(String action, boolean startedByTrustedSource)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 
createParams(boolean startedByTrustedSource, boolean skipEncryption, String wifiSsid, String action, String packageName)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 
verifyInitiateProfileOwnerUi()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 
verifyInitiateDeviceOwnerUi()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