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.preprovisioning; 17 18 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE; 19 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE; 20 21 import static org.mockito.Mockito.any; 22 import static org.mockito.Mockito.never; 23 import static org.mockito.Mockito.verify; 24 import static org.mockito.Mockito.when; 25 26 import android.content.ComponentName; 27 import android.content.Context; 28 import android.content.Intent; 29 import android.content.pm.PackageManager; 30 import android.content.res.Resources; 31 import android.os.Handler; 32 import android.os.Looper; 33 import android.test.AndroidTestCase; 34 35 import androidx.test.filters.SmallTest; 36 37 import com.android.managedprovisioning.common.NotificationHelper; 38 import com.android.managedprovisioning.common.SettingsFacade; 39 import com.android.managedprovisioning.common.Utils; 40 import com.android.managedprovisioning.model.ProvisioningParams; 41 42 import org.mockito.ArgumentCaptor; 43 import org.mockito.Mock; 44 import org.mockito.MockitoAnnotations; 45 46 import java.util.concurrent.Semaphore; 47 import java.util.concurrent.TimeUnit; 48 49 @SmallTest 50 public class EncryptionControllerTest extends AndroidTestCase { 51 private static final int TEST_USER_ID = 10; 52 private static final String MP_PACKAGE_NAME = "com.android.managedprovisioning"; 53 private static final ComponentName TEST_HOME_RECEIVER = new ComponentName(MP_PACKAGE_NAME, 54 ".HomeReceiverActivity"); 55 private static final String TEST_MDM_PACKAGE = "com.admin.test"; 56 private static final int RESUME_PROVISIONING_TIMEOUT_MS = 1000; 57 58 @Mock private Context mContext; 59 @Mock private Utils mUtils; 60 @Mock private SettingsFacade mSettingsFacade; 61 @Mock private Resources mResources; 62 @Mock private PackageManager mPackageManager; 63 @Mock private NotificationHelper mNotificationHelper; 64 65 private EncryptionController mController; 66 67 @Override setUp()68 public void setUp() { 69 // this is necessary for mockito to work 70 System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString()); 71 72 MockitoAnnotations.initMocks(this); 73 74 when(mUtils.isPhysicalDeviceEncrypted()).thenReturn(true); 75 when(mContext.getApplicationContext()).thenReturn(mContext); 76 when(mContext.getPackageManager()).thenReturn(mPackageManager); 77 when(mContext.getFilesDir()).thenReturn(getContext().getFilesDir()); 78 79 mController = createEncryptionController(); 80 mController.getProvisioningParamsFile(mContext).delete(); 81 } 82 testDeviceOwner()83 public void testDeviceOwner() throws Exception { 84 // GIVEN we've set a provisioning reminder for device owner provisioning. 85 when(mSettingsFacade.isUserSetupCompleted(mContext)).thenReturn(false); 86 ProvisioningParams params = createProvisioningParams(ACTION_PROVISION_MANAGED_DEVICE); 87 setReminder(params); 88 verify(mUtils).enableComponent(TEST_HOME_RECEIVER, TEST_USER_ID); 89 verify(mPackageManager).flushPackageRestrictionsAsUser(TEST_USER_ID); 90 // WHEN resuming the provisioning 91 runResumeProvisioningOnUiThread(); 92 // THEN the pre provisioning activity is started 93 verifyStartPreProvisioningActivity(params); 94 } 95 testProfileOwnerAfterSuw()96 public void testProfileOwnerAfterSuw() throws Exception { 97 // GIVEN we set a provisioning reminder for managed profile provisioning after SUW 98 when(mSettingsFacade.isUserSetupCompleted(mContext)).thenReturn(true); 99 ProvisioningParams params = createProvisioningParams(ACTION_PROVISION_MANAGED_PROFILE); 100 setReminder(params); 101 // WHEN resuming the provisioning 102 runResumeProvisioningOnUiThread(); 103 // THEN we show a notification 104 verifyShowResumeNotification(params); 105 } 106 testProfileOwnerDuringSuw()107 public void testProfileOwnerDuringSuw() throws Exception { 108 // GIVEN we set a provisioning reminder for managed profile provisioning during SUW 109 when(mSettingsFacade.isUserSetupCompleted(mContext)).thenReturn(false); 110 ProvisioningParams params = createProvisioningParams(ACTION_PROVISION_MANAGED_PROFILE); 111 setReminder(params); 112 verify(mUtils).enableComponent(TEST_HOME_RECEIVER, TEST_USER_ID); 113 verify(mPackageManager).flushPackageRestrictionsAsUser(TEST_USER_ID); 114 // WHEN resuming the provisioning 115 runResumeProvisioningOnUiThread(); 116 // THEN we start the pre provisioning activity 117 verifyStartPreProvisioningActivity(params); 118 } 119 testDeviceNotEncrypted()120 public void testDeviceNotEncrypted() throws Exception { 121 // GIVEN an intent was stored to resume device owner provisioning, but the device 122 // is not encrypted 123 ProvisioningParams params = createProvisioningParams(ACTION_PROVISION_MANAGED_DEVICE); 124 setReminder(params); 125 when(mUtils.isPhysicalDeviceEncrypted()).thenReturn(false); 126 // WHEN resuming provisioning 127 runResumeProvisioningOnUiThread(); 128 // THEN nothing should happen 129 verifyNothingStarted(); 130 } 131 testResumeProvisioningNoIntent()132 public void testResumeProvisioningNoIntent() throws Exception { 133 // GIVEN no reminder is set 134 // WHEN resuming the provisioning 135 runResumeProvisioningOnUiThread(); 136 // THEN nothing should happen 137 verifyNothingStarted(); 138 } 139 testCancelProvisioningReminder()140 public void testCancelProvisioningReminder() throws Exception { 141 // WHEN we've set a provisioning reminder 142 when(mSettingsFacade.isUserSetupCompleted(mContext)).thenReturn(true); 143 ProvisioningParams params = createProvisioningParams(ACTION_PROVISION_MANAGED_PROFILE); 144 setReminder(params); 145 // WHEN canceling the reminder and then resuming the provisioning 146 mController.cancelEncryptionReminder(); 147 verify(mUtils).disableComponent(TEST_HOME_RECEIVER, TEST_USER_ID); 148 runResumeProvisioningOnUiThread(); 149 // THEN nothing should start 150 verifyNothingStarted(); 151 } 152 createProvisioningParams(String action)153 private ProvisioningParams createProvisioningParams(String action) { 154 return new ProvisioningParams.Builder() 155 .setProvisioningAction(action) 156 .setDeviceAdminPackageName(TEST_MDM_PACKAGE) 157 .build(); 158 } 159 runResumeProvisioningOnUiThread()160 private void runResumeProvisioningOnUiThread() throws InterruptedException { 161 final Semaphore semaphore = new Semaphore(0); 162 new Handler(Looper.getMainLooper()).post(new Runnable() { 163 @Override 164 public void run() { 165 // In a real case, the device may have rebooted between the moment when the 166 // reminder was set and the moment we resume the provisioning. Recreate the 167 // encryption controller to simulate this. 168 createEncryptionController().resumeProvisioning(); 169 semaphore.release(); 170 } 171 }); 172 assertTrue("Timeout trying to resume provisioning", 173 semaphore.tryAcquire(RESUME_PROVISIONING_TIMEOUT_MS, TimeUnit.MILLISECONDS)); 174 } 175 createEncryptionController()176 private EncryptionController createEncryptionController() { 177 return new EncryptionController(mContext, mUtils, mSettingsFacade, TEST_HOME_RECEIVER, 178 mNotificationHelper, TEST_USER_ID); 179 } 180 setReminder(ProvisioningParams params)181 private void setReminder(ProvisioningParams params) { 182 mController.setEncryptionReminder(params); 183 } 184 verifyStartPreProvisioningActivity(ProvisioningParams params)185 private void verifyStartPreProvisioningActivity(ProvisioningParams params) throws Exception { 186 ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); 187 verify(mContext).startActivity(intentCaptor.capture()); 188 assertEquals(params, intentCaptor.getValue().getParcelableExtra( 189 ProvisioningParams.EXTRA_PROVISIONING_PARAMS)); 190 verify(mNotificationHelper, never()).showResumeNotification(any(Intent.class)); 191 } 192 verifyShowResumeNotification(ProvisioningParams params)193 private void verifyShowResumeNotification(ProvisioningParams params) throws Exception { 194 ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); 195 verify(mNotificationHelper).showResumeNotification(intentCaptor.capture()); 196 assertEquals(params, intentCaptor.getValue().getParcelableExtra( 197 ProvisioningParams.EXTRA_PROVISIONING_PARAMS)); 198 verify(mContext, never()).startActivity(any(Intent.class)); 199 } 200 verifyNothingStarted()201 private void verifyNothingStarted() throws Exception { 202 verify(mContext, never()).startActivity(any(Intent.class)); 203 verify(mNotificationHelper, never()).showResumeNotification(any(Intent.class)); 204 } 205 } 206