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