1 /* 2 * Copyright 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 17 package com.android.managedprovisioning.finalization; 18 19 import static android.app.admin.DeviceAdminReceiver.ACTION_PROFILE_PROVISIONING_COMPLETE; 20 import static android.app.admin.DevicePolicyManager.ACTION_PROVISIONING_SUCCESSFUL; 21 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE; 22 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE; 23 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE; 24 import static com.android.managedprovisioning.TestUtils.createTestAdminExtras; 25 import static org.mockito.Matchers.any; 26 import static org.mockito.Matchers.anyInt; 27 import static org.mockito.Matchers.eq; 28 import static org.mockito.Mockito.never; 29 import static org.mockito.Mockito.verify; 30 import static org.mockito.Mockito.when; 31 32 import android.app.Activity; 33 import android.content.BroadcastReceiver; 34 import android.content.ComponentName; 35 import android.content.Context; 36 import android.content.Intent; 37 import android.os.PersistableBundle; 38 import android.os.UserHandle; 39 import android.test.AndroidTestCase; 40 import android.test.suitebuilder.annotation.SmallTest; 41 42 import com.android.managedprovisioning.TestUtils; 43 import com.android.managedprovisioning.common.SettingsFacade; 44 import com.android.managedprovisioning.common.Utils; 45 import com.android.managedprovisioning.model.ProvisioningParams; 46 47 import org.mockito.ArgumentCaptor; 48 import org.mockito.Mock; 49 import org.mockito.MockitoAnnotations; 50 51 /** 52 * Unit tests for {@link FinalizationController}. 53 */ 54 public class FinalizationControllerTest extends AndroidTestCase { 55 private static final UserHandle MANAGED_PROFILE_USER_HANDLE = UserHandle.of(123); 56 private static final String TEST_MDM_PACKAGE_NAME = "mdm.package.name"; 57 private static final String TEST_MDM_ADMIN_RECEIVER = TEST_MDM_PACKAGE_NAME + ".AdminReceiver"; 58 private static final ComponentName TEST_MDM_ADMIN = new ComponentName(TEST_MDM_PACKAGE_NAME, 59 TEST_MDM_ADMIN_RECEIVER); 60 private static final PersistableBundle TEST_MDM_EXTRA_BUNDLE = createTestAdminExtras(); 61 62 @Mock private Context mContext; 63 @Mock private Utils mUtils; 64 @Mock private SettingsFacade mSettingsFacade; 65 @Mock private UserProvisioningStateHelper mHelper; 66 67 private FinalizationController mController; 68 69 @Override setUp()70 public void setUp() throws Exception { 71 // this is necessary for mockito to work 72 System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString()); 73 MockitoAnnotations.initMocks(this); 74 when(mUtils.canResolveIntentAsUser(any(Context.class), any(Intent.class), anyInt())) 75 .thenReturn(true); 76 when(mContext.getFilesDir()).thenReturn(getContext().getFilesDir()); 77 78 mController = new FinalizationController(mContext, mUtils, mSettingsFacade, mHelper); 79 } 80 81 @Override tearDown()82 public void tearDown() throws Exception { 83 mController.loadProvisioningParamsAndClearFile(); 84 } 85 86 @SmallTest testInitiallyDone_alreadyCalled()87 public void testInitiallyDone_alreadyCalled() { 88 // GIVEN that provisioningInitiallyDone has already been called 89 when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(false); 90 final ProvisioningParams params = createProvisioningParams( 91 ACTION_PROVISION_MANAGED_PROFILE); 92 93 // WHEN calling provisioningInitiallyDone 94 mController.provisioningInitiallyDone(params); 95 96 // THEN nothing should happen 97 verify(mHelper, never()).markUserProvisioningStateInitiallyDone(params); 98 verify(mHelper, never()).markUserProvisioningStateFinalized(params); 99 } 100 101 @SmallTest testFinalized_alreadyCalled()102 public void testFinalized_alreadyCalled() { 103 // GIVEN that provisioningInitiallyDone has already been called 104 when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(true); 105 final ProvisioningParams params = createProvisioningParams( 106 ACTION_PROVISION_MANAGED_PROFILE); 107 108 // WHEN calling provisioningFinalized 109 mController.provisioningFinalized(); 110 111 // THEN nothing should happen 112 verify(mHelper, never()).markUserProvisioningStateInitiallyDone(params); 113 verify(mHelper, never()).markUserProvisioningStateFinalized(params); 114 } 115 116 @SmallTest testFinalized_noParamsStored()117 public void testFinalized_noParamsStored() { 118 // GIVEN that the user provisioning state is correct 119 when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(false); 120 121 // WHEN calling provisioningFinalized 122 mController.provisioningFinalized(); 123 124 // THEN nothing should happen 125 verify(mHelper, never()) 126 .markUserProvisioningStateInitiallyDone(any(ProvisioningParams.class)); 127 verify(mHelper, never()).markUserProvisioningStateFinalized(any(ProvisioningParams.class)); 128 } 129 130 @SmallTest testManagedProfileAfterSuw()131 public void testManagedProfileAfterSuw() { 132 // GIVEN that provisioningInitiallyDone has never been called 133 when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(true); 134 // GIVEN that we've provisioned a managed profile after SUW 135 final ProvisioningParams params = createProvisioningParams( 136 ACTION_PROVISION_MANAGED_PROFILE); 137 when(mSettingsFacade.isUserSetupCompleted(mContext)).thenReturn(true); 138 when(mUtils.getManagedProfile(mContext)) 139 .thenReturn(MANAGED_PROFILE_USER_HANDLE); 140 141 // WHEN calling provisioningInitiallyDone 142 mController.provisioningInitiallyDone(params); 143 144 // THEN the user provisioning state should be marked as initially done 145 verify(mHelper).markUserProvisioningStateInitiallyDone(params); 146 147 // THEN provisioning successful intent should be sent to the dpc. 148 verifyDpcLaunchedForUser(MANAGED_PROFILE_USER_HANDLE); 149 150 // THEN an ordered broadcast should be sent to the DPC 151 verifyOrderedBroadcast(); 152 } 153 154 @SmallTest testManagedProfileDuringSuw()155 public void testManagedProfileDuringSuw() { 156 // GIVEN that provisioningInitiallyDone has never been called 157 when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(true); 158 // GIVEN that we've provisioned a managed profile after SUW 159 final ProvisioningParams params = createProvisioningParams( 160 ACTION_PROVISION_MANAGED_PROFILE); 161 when(mSettingsFacade.isUserSetupCompleted(mContext)).thenReturn(false); 162 when(mUtils.getManagedProfile(mContext)) 163 .thenReturn(MANAGED_PROFILE_USER_HANDLE); 164 165 // WHEN calling provisioningInitiallyDone 166 mController.provisioningInitiallyDone(params); 167 168 // THEN the user provisioning state should be marked as initially done 169 verify(mHelper).markUserProvisioningStateInitiallyDone(params); 170 // THEN the provisioning params have been stored and will be read in provisioningFinalized 171 172 // GIVEN that the provisioning state is now incomplete 173 when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(false); 174 175 // WHEN calling provisioningFinalized 176 mController.provisioningFinalized(); 177 178 // THEN the user provisioning state is finalized 179 verify(mHelper).markUserProvisioningStateFinalized(params); 180 181 // THEN provisioning successful intent should be sent to the dpc. 182 verifyDpcLaunchedForUser(MANAGED_PROFILE_USER_HANDLE); 183 184 // THEN an ordered broadcast should be sent to the DPC 185 verifyOrderedBroadcast(); 186 } 187 188 @SmallTest testDeviceOwner()189 public void testDeviceOwner() { 190 // GIVEN that provisioningInitiallyDone has never been called 191 when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(true); 192 // GIVEN that we've provisioned a managed profile after SUW 193 final ProvisioningParams params = createProvisioningParams( 194 ACTION_PROVISION_MANAGED_DEVICE); 195 when(mSettingsFacade.isUserSetupCompleted(mContext)).thenReturn(false); 196 197 // WHEN calling provisioningInitiallyDone 198 mController.provisioningInitiallyDone(params); 199 200 // THEN the user provisioning state should be marked as initially done 201 verify(mHelper).markUserProvisioningStateInitiallyDone(params); 202 // THEN the provisioning params have been stored and will be read in provisioningFinalized 203 204 // GIVEN that the provisioning state is now incomplete 205 when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(false); 206 207 // WHEN calling provisioningFinalized 208 mController.provisioningFinalized(); 209 210 // THEN the user provisioning state is finalized 211 verify(mHelper).markUserProvisioningStateFinalized(params); 212 213 // THEN provisioning successful intent should be sent to the dpc. 214 verifyDpcLaunchedForUser(UserHandle.of(UserHandle.myUserId())); 215 216 // THEN a broadcast was sent to the primary user 217 ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); 218 verify(mContext).sendBroadcast(intentCaptor.capture()); 219 220 // THEN the intent should be ACTION_PROFILE_PROVISIONING_COMPLETE 221 assertEquals(ACTION_PROFILE_PROVISIONING_COMPLETE, intentCaptor.getValue().getAction()); 222 // THEN the intent should be sent to the admin receiver 223 assertEquals(TEST_MDM_ADMIN, intentCaptor.getValue().getComponent()); 224 // THEN the admin extras bundle should contain mdm extras 225 assertExtras(intentCaptor.getValue()); 226 } 227 verifyOrderedBroadcast()228 private void verifyOrderedBroadcast() { 229 // THEN an ordered broadcast should be sent to the DPC 230 ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); 231 verify(mContext).sendOrderedBroadcastAsUser( 232 intentCaptor.capture(), 233 eq(MANAGED_PROFILE_USER_HANDLE), 234 eq(null), 235 any(BroadcastReceiver.class), 236 eq(null), 237 eq(Activity.RESULT_OK), 238 eq(null), 239 eq(null)); 240 // THEN the intent should be ACTION_PROFILE_PROVISIONING_COMPLETE 241 assertEquals(ACTION_PROFILE_PROVISIONING_COMPLETE, intentCaptor.getValue().getAction()); 242 // THEN the intent should be sent to the admin receiver 243 assertEquals(TEST_MDM_ADMIN, intentCaptor.getValue().getComponent()); 244 // THEN the admin extras bundle should contain mdm extras 245 assertExtras(intentCaptor.getValue()); 246 } 247 verifyDpcLaunchedForUser(UserHandle userHandle)248 private void verifyDpcLaunchedForUser(UserHandle userHandle) { 249 ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); 250 verify(mContext).startActivityAsUser(intentCaptor.capture(), eq(userHandle)); 251 // THEN the intent should be ACTION_PROVISIONING_SUCCESSFUL 252 assertEquals(ACTION_PROVISIONING_SUCCESSFUL, intentCaptor.getValue().getAction()); 253 // THEN the intent should only be sent to the dpc 254 assertEquals(TEST_MDM_PACKAGE_NAME, intentCaptor.getValue().getPackage()); 255 // THEN the admin extras bundle should contain mdm extras 256 assertExtras(intentCaptor.getValue()); 257 } 258 assertExtras(Intent intent)259 private void assertExtras(Intent intent) { 260 TestUtils.bundleEquals(TEST_MDM_EXTRA_BUNDLE, 261 (PersistableBundle) intent.getExtra(EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE)); 262 } 263 createProvisioningParams(String action)264 private ProvisioningParams createProvisioningParams(String action) { 265 return new ProvisioningParams.Builder() 266 .setDeviceAdminComponentName(TEST_MDM_ADMIN) 267 .setProvisioningAction(action) 268 .setAdminExtrasBundle(TEST_MDM_EXTRA_BUNDLE) 269 .build(); 270 } 271 } 272