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 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.findDeviceAdmin(null, TEST_MDM_ADMIN, mContext)) 75 .thenReturn(TEST_MDM_ADMIN); 76 when(mUtils.canResolveIntentAsUser(any(Context.class), any(Intent.class), anyInt())) 77 .thenReturn(true); 78 when(mContext.getFilesDir()).thenReturn(getContext().getFilesDir()); 79 80 mController = new FinalizationController(mContext, mUtils, mSettingsFacade, mHelper); 81 } 82 83 @Override 84 public void tearDown() throws Exception { 85 mController.loadProvisioningParamsAndClearFile(); 86 } 87 88 @SmallTest 89 public void testInitiallyDone_alreadyCalled() { 90 // GIVEN that provisioningInitiallyDone has already been called 91 when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(false); 92 final ProvisioningParams params = createProvisioningParams( 93 ACTION_PROVISION_MANAGED_PROFILE); 94 95 // WHEN calling provisioningInitiallyDone 96 mController.provisioningInitiallyDone(params); 97 98 // THEN nothing should happen 99 verify(mHelper, never()).markUserProvisioningStateInitiallyDone(params); 100 verify(mHelper, never()).markUserProvisioningStateFinalized(params); 101 } 102 103 @SmallTest 104 public void testFinalized_alreadyCalled() { 105 // GIVEN that provisioningInitiallyDone has already been called 106 when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(true); 107 final ProvisioningParams params = createProvisioningParams( 108 ACTION_PROVISION_MANAGED_PROFILE); 109 110 // WHEN calling provisioningFinalized 111 mController.provisioningFinalized(); 112 113 // THEN nothing should happen 114 verify(mHelper, never()).markUserProvisioningStateInitiallyDone(params); 115 verify(mHelper, never()).markUserProvisioningStateFinalized(params); 116 } 117 118 @SmallTest 119 public void testFinalized_noParamsStored() { 120 // GIVEN that the user provisioning state is correct 121 when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(false); 122 123 // WHEN calling provisioningFinalized 124 mController.provisioningFinalized(); 125 126 // THEN nothing should happen 127 verify(mHelper, never()) 128 .markUserProvisioningStateInitiallyDone(any(ProvisioningParams.class)); 129 verify(mHelper, never()).markUserProvisioningStateFinalized(any(ProvisioningParams.class)); 130 } 131 132 @SmallTest 133 public void testManagedProfileAfterSuw() { 134 // GIVEN that provisioningInitiallyDone has never been called 135 when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(true); 136 // GIVEN that we've provisioned a managed profile after SUW 137 final ProvisioningParams params = createProvisioningParams( 138 ACTION_PROVISION_MANAGED_PROFILE); 139 when(mSettingsFacade.isUserSetupCompleted(mContext)).thenReturn(true); 140 when(mUtils.getManagedProfile(mContext)) 141 .thenReturn(MANAGED_PROFILE_USER_HANDLE); 142 143 // WHEN calling provisioningInitiallyDone 144 mController.provisioningInitiallyDone(params); 145 146 // THEN the user provisioning state should be marked as initially done 147 verify(mHelper).markUserProvisioningStateInitiallyDone(params); 148 149 // THEN provisioning successful intent should be sent to the dpc. 150 verifyDpcLaunchedForUser(MANAGED_PROFILE_USER_HANDLE); 151 152 // THEN an ordered broadcast should be sent to the DPC 153 verifyOrderedBroadcast(); 154 } 155 156 @SmallTest 157 public void testManagedProfileDuringSuw() { 158 // GIVEN that provisioningInitiallyDone has never been called 159 when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(true); 160 // GIVEN that we've provisioned a managed profile after SUW 161 final ProvisioningParams params = createProvisioningParams( 162 ACTION_PROVISION_MANAGED_PROFILE); 163 when(mSettingsFacade.isUserSetupCompleted(mContext)).thenReturn(false); 164 when(mUtils.getManagedProfile(mContext)) 165 .thenReturn(MANAGED_PROFILE_USER_HANDLE); 166 167 // WHEN calling provisioningInitiallyDone 168 mController.provisioningInitiallyDone(params); 169 170 // THEN the user provisioning state should be marked as initially done 171 verify(mHelper).markUserProvisioningStateInitiallyDone(params); 172 // THEN the provisioning params have been stored and will be read in provisioningFinalized 173 174 // GIVEN that the provisioning state is now incomplete 175 when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(false); 176 177 // WHEN calling provisioningFinalized 178 mController.provisioningFinalized(); 179 180 // THEN the user provisioning state is finalized 181 verify(mHelper).markUserProvisioningStateFinalized(params); 182 183 // THEN provisioning successful intent should be sent to the dpc. 184 verifyDpcLaunchedForUser(MANAGED_PROFILE_USER_HANDLE); 185 186 // THEN an ordered broadcast should be sent to the DPC 187 verifyOrderedBroadcast(); 188 } 189 190 @SmallTest 191 public void testDeviceOwner() { 192 // GIVEN that provisioningInitiallyDone has never been called 193 when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(true); 194 // GIVEN that we've provisioned a managed profile after SUW 195 final ProvisioningParams params = createProvisioningParams( 196 ACTION_PROVISION_MANAGED_DEVICE); 197 when(mSettingsFacade.isUserSetupCompleted(mContext)).thenReturn(false); 198 199 // WHEN calling provisioningInitiallyDone 200 mController.provisioningInitiallyDone(params); 201 202 // THEN the user provisioning state should be marked as initially done 203 verify(mHelper).markUserProvisioningStateInitiallyDone(params); 204 // THEN the provisioning params have been stored and will be read in provisioningFinalized 205 206 // GIVEN that the provisioning state is now incomplete 207 when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(false); 208 209 // WHEN calling provisioningFinalized 210 mController.provisioningFinalized(); 211 212 // THEN the user provisioning state is finalized 213 verify(mHelper).markUserProvisioningStateFinalized(params); 214 215 // THEN provisioning successful intent should be sent to the dpc. 216 verifyDpcLaunchedForUser(UserHandle.of(UserHandle.myUserId())); 217 218 // THEN a broadcast was sent to the primary user 219 ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); 220 verify(mContext).sendBroadcast(intentCaptor.capture()); 221 222 // THEN the intent should be ACTION_PROFILE_PROVISIONING_COMPLETE 223 assertEquals(ACTION_PROFILE_PROVISIONING_COMPLETE, intentCaptor.getValue().getAction()); 224 // THEN the intent should be sent to the admin receiver 225 assertEquals(TEST_MDM_ADMIN, intentCaptor.getValue().getComponent()); 226 // THEN the admin extras bundle should contain mdm extras 227 assertExtras(intentCaptor.getValue()); 228 } 229 230 private void verifyOrderedBroadcast() { 231 // THEN an ordered broadcast should be sent to the DPC 232 ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); 233 verify(mContext).sendOrderedBroadcastAsUser( 234 intentCaptor.capture(), 235 eq(MANAGED_PROFILE_USER_HANDLE), 236 eq(null), 237 any(BroadcastReceiver.class), 238 eq(null), 239 eq(Activity.RESULT_OK), 240 eq(null), 241 eq(null)); 242 // THEN the intent should be ACTION_PROFILE_PROVISIONING_COMPLETE 243 assertEquals(ACTION_PROFILE_PROVISIONING_COMPLETE, intentCaptor.getValue().getAction()); 244 // THEN the intent should be sent to the admin receiver 245 assertEquals(TEST_MDM_ADMIN, intentCaptor.getValue().getComponent()); 246 // THEN the admin extras bundle should contain mdm extras 247 assertExtras(intentCaptor.getValue()); 248 } 249 250 private void verifyDpcLaunchedForUser(UserHandle userHandle) { 251 ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); 252 verify(mContext).startActivityAsUser(intentCaptor.capture(), eq(userHandle)); 253 // THEN the intent should be ACTION_PROVISIONING_SUCCESSFUL 254 assertEquals(ACTION_PROVISIONING_SUCCESSFUL, intentCaptor.getValue().getAction()); 255 // THEN the intent should only be sent to the dpc 256 assertEquals(TEST_MDM_PACKAGE_NAME, intentCaptor.getValue().getPackage()); 257 // THEN the admin extras bundle should contain mdm extras 258 assertExtras(intentCaptor.getValue()); 259 } 260 261 private void assertExtras(Intent intent) { 262 TestUtils.bundleEquals(TEST_MDM_EXTRA_BUNDLE, 263 (PersistableBundle) intent.getExtra(EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE)); 264 } 265 266 private ProvisioningParams createProvisioningParams(String action) { 267 return new ProvisioningParams.Builder() 268 .setDeviceAdminComponentName(TEST_MDM_ADMIN) 269 .setProvisioningAction(action) 270 .setAdminExtrasBundle(TEST_MDM_EXTRA_BUNDLE) 271 .build(); 272 } 273 } 274