1 /* 2 * Copyright 2018, 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.finalization; 17 18 import static android.app.admin.DeviceAdminReceiver.ACTION_PROFILE_PROVISIONING_COMPLETE; 19 import static android.app.admin.DevicePolicyManager.ACTION_ADMIN_POLICY_COMPLIANCE; 20 import static android.app.admin.DevicePolicyManager.ACTION_PROVISIONING_SUCCESSFUL; 21 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE; 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 android.app.admin.DevicePolicyManager.PROVISIONING_TRIGGER_MANAGED_ACCOUNT; 25 26 import static com.google.common.truth.Truth.assertThat; 27 28 import static org.mockito.ArgumentMatchers.any; 29 import static org.mockito.ArgumentMatchers.anyInt; 30 import static org.mockito.ArgumentMatchers.anyString; 31 import static org.mockito.ArgumentMatchers.eq; 32 import static org.mockito.Mockito.never; 33 import static org.mockito.Mockito.verify; 34 import static org.mockito.Mockito.when; 35 36 import android.content.ComponentName; 37 import android.content.Context; 38 import android.content.Intent; 39 import android.content.SharedPreferences; 40 import android.os.PersistableBundle; 41 import android.os.UserHandle; 42 43 import androidx.test.InstrumentationRegistry; 44 45 import com.android.managedprovisioning.analytics.ProvisioningAnalyticsTracker; 46 import com.android.managedprovisioning.common.IllegalProvisioningArgumentException; 47 import com.android.managedprovisioning.common.PolicyComplianceUtils; 48 import com.android.managedprovisioning.common.SettingsFacade; 49 import com.android.managedprovisioning.common.Utils; 50 import com.android.managedprovisioning.model.ProvisioningParams; 51 52 import org.junit.Before; 53 import org.junit.Test; 54 import org.mockito.ArgumentCaptor; 55 import org.mockito.Mock; 56 import org.mockito.MockitoAnnotations; 57 58 /** 59 * Unit tests for {@link ProvisioningIntentProvider}. 60 */ 61 public class ProvisioningIntentProviderTest { 62 63 private static final String DEVICE_ADMIN_PACKAGE_NAME = "com.example.package"; 64 private static final ComponentName DEVICE_ADMIN_COMPONENT_NAME = 65 new ComponentName(DEVICE_ADMIN_PACKAGE_NAME, "com.android.AdminReceiver"); 66 private static final PersistableBundle ADMIN_EXTRAS_BUNDLE = 67 PersistableBundle.forPair("test_key", "test_value"); 68 private static final UserHandle WORK_PROFILE_USER_HANDLE = UserHandle.of(10); 69 private static final ProvisioningParams ADMIN_INTEGRATED_FLOW_PARAMS = 70 new ProvisioningParams.Builder() 71 .setProvisioningAction(ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE) 72 .setDeviceAdminComponentName(DEVICE_ADMIN_COMPONENT_NAME) 73 .setAdminExtrasBundle(ADMIN_EXTRAS_BUNDLE) 74 .setStartedByTrustedSource(true) 75 .setFlowType(ProvisioningParams.FLOW_TYPE_ADMIN_INTEGRATED) 76 .build(); 77 private static final ProvisioningParams LEGACY_FLOW_PARAMS = new ProvisioningParams.Builder() 78 .setDeviceAdminComponentName(DEVICE_ADMIN_COMPONENT_NAME) 79 .setProvisioningAction(ACTION_PROVISION_MANAGED_PROFILE) 80 .setAdminExtrasBundle(ADMIN_EXTRAS_BUNDLE) 81 .build(); 82 private static final ProvisioningParams LEGACY_FLOW_PARAMS_WITH_PROVISIONING_TRIGGER = 83 new ProvisioningParams.Builder() 84 .setDeviceAdminComponentName(DEVICE_ADMIN_COMPONENT_NAME) 85 .setProvisioningAction(ACTION_PROVISION_MANAGED_PROFILE) 86 .setAdminExtrasBundle(ADMIN_EXTRAS_BUNDLE) 87 .setProvisioningTrigger(PROVISIONING_TRIGGER_MANAGED_ACCOUNT) 88 .build(); 89 90 @Mock private Context mContext; 91 @Mock private Utils mUtils; 92 @Mock private ProvisioningAnalyticsTracker mProvisioningAnalyticsTracker; 93 @Mock private PolicyComplianceUtils mPolicyComplianceUtils; 94 @Mock private SettingsFacade mSettingsFacade; 95 @Mock private SharedPreferences mSharedPreferences; 96 97 private final ProvisioningIntentProvider mProvisioningIntentProvider = 98 new ProvisioningIntentProvider(); 99 private final Context mTargetContext = InstrumentationRegistry.getTargetContext(); 100 101 @Before setUp()102 public void setUp() { 103 MockitoAnnotations.initMocks(this); 104 when(mContext.getSharedPreferences(anyString(), anyInt())).thenReturn(mSharedPreferences); 105 when(mContext.getResources()).thenReturn(mTargetContext.getResources()); 106 } 107 108 @Test maybeLaunchDpc_adminIntegratedFlow_policyComplianceActionLaunched()109 public void maybeLaunchDpc_adminIntegratedFlow_policyComplianceActionLaunched() { 110 when(mUtils.canResolveIntentAsUser(any(), any(), anyInt())).thenReturn(true); 111 PolicyComplianceUtils policyComplianceUtils = new PolicyComplianceUtils(); 112 113 mProvisioningIntentProvider.maybeLaunchDpc(ADMIN_INTEGRATED_FLOW_PARAMS, 0, mUtils, 114 mContext, mProvisioningAnalyticsTracker, policyComplianceUtils, mSettingsFacade); 115 116 ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); 117 verify(mContext).startActivityAsUser(intentCaptor.capture(), any()); 118 verify(mProvisioningAnalyticsTracker).logDpcSetupStarted(any(), any()); 119 assertThat(intentCaptor.getValue().getAction()).isEqualTo(ACTION_ADMIN_POLICY_COMPLIANCE); 120 } 121 122 @Test maybeLaunchDpc_legacyFlow_provisioningSuccessfulLaunched()123 public void maybeLaunchDpc_legacyFlow_provisioningSuccessfulLaunched() { 124 makeProvisioningSuccessfulIntentResolvable(); 125 PolicyComplianceUtils policyComplianceUtils = new PolicyComplianceUtils(); 126 127 mProvisioningIntentProvider.maybeLaunchDpc(LEGACY_FLOW_PARAMS, 0, mUtils, mContext, 128 mProvisioningAnalyticsTracker, policyComplianceUtils, mSettingsFacade); 129 130 ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); 131 verify(mContext).startActivityAsUser(intentCaptor.capture(), any()); 132 verify(mProvisioningAnalyticsTracker).logDpcSetupStarted(any(), any()); 133 assertThat(intentCaptor.getValue().getAction()).isEqualTo(ACTION_PROVISIONING_SUCCESSFUL); 134 } 135 136 @Test maybeLaunchDpc_legacyFlow_duringSetupWizard_provisioningSuccessfulLaunched()137 public void maybeLaunchDpc_legacyFlow_duringSetupWizard_provisioningSuccessfulLaunched() { 138 when(mUtils.canResolveIntentAsUser(any(), any(), anyInt())).thenReturn(true); 139 when(mSettingsFacade.isDuringSetupWizard(mContext)).thenReturn(false); 140 PolicyComplianceUtils policyComplianceUtils = new PolicyComplianceUtils(); 141 142 mProvisioningIntentProvider.maybeLaunchDpc(LEGACY_FLOW_PARAMS, 0, mUtils, mContext, 143 mProvisioningAnalyticsTracker, policyComplianceUtils, mSettingsFacade); 144 145 ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); 146 verify(mContext).startActivityAsUser(intentCaptor.capture(), any()); 147 verify(mProvisioningAnalyticsTracker).logDpcSetupStarted(any(), any()); 148 assertThat(intentCaptor.getValue().getAction()).isEqualTo(ACTION_PROVISIONING_SUCCESSFUL); 149 } 150 151 @Test maybeLaunchDpc_legacyFlow_duringSetupWizard_policyComplianceResolvable_policyComplianceLaunched()152 public void maybeLaunchDpc_legacyFlow_duringSetupWizard_policyComplianceResolvable_policyComplianceLaunched() { 153 when(mUtils.canResolveIntentAsUser(any(), any(), anyInt())).thenReturn(true); 154 when(mUtils.getManagedProfile(mContext)).thenReturn(WORK_PROFILE_USER_HANDLE); 155 when(mSettingsFacade.isDuringSetupWizard(mContext)).thenReturn(true); 156 PolicyComplianceUtils policyComplianceUtils = new PolicyComplianceUtils(); 157 158 mProvisioningIntentProvider.maybeLaunchDpc( 159 LEGACY_FLOW_PARAMS, WORK_PROFILE_USER_HANDLE.getIdentifier(), mUtils, mContext, 160 mProvisioningAnalyticsTracker, policyComplianceUtils, mSettingsFacade); 161 162 ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); 163 verify(mContext).startActivityAsUser(intentCaptor.capture(), any()); 164 verify(mProvisioningAnalyticsTracker).logDpcSetupStarted(any(), any()); 165 assertThat(intentCaptor.getValue().getAction()).isEqualTo(ACTION_ADMIN_POLICY_COMPLIANCE); 166 } 167 168 @Test maybeLaunchDpc_legacyFlow_policyComplianceResolvable_hasProvisioningTrigger_provisioningSuccessfulLaunched()169 public void maybeLaunchDpc_legacyFlow_policyComplianceResolvable_hasProvisioningTrigger_provisioningSuccessfulLaunched() { 170 when(mUtils.canResolveIntentAsUser(any(), any(), anyInt())).thenReturn(true); 171 when(mUtils.getManagedProfile(mContext)).thenReturn(WORK_PROFILE_USER_HANDLE); 172 when(mSettingsFacade.isDuringSetupWizard(mContext)).thenReturn(true); 173 PolicyComplianceUtils policyComplianceUtils = new PolicyComplianceUtils(); 174 175 mProvisioningIntentProvider.maybeLaunchDpc( 176 LEGACY_FLOW_PARAMS_WITH_PROVISIONING_TRIGGER, 177 WORK_PROFILE_USER_HANDLE.getIdentifier(), mUtils, mContext, 178 mProvisioningAnalyticsTracker, policyComplianceUtils, mSettingsFacade); 179 180 ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); 181 verify(mContext).startActivityAsUser(intentCaptor.capture(), any()); 182 verify(mProvisioningAnalyticsTracker).logDpcSetupStarted(any(), any()); 183 assertThat(intentCaptor.getValue().getAction()).isEqualTo(ACTION_PROVISIONING_SUCCESSFUL); 184 } 185 186 @Test maybeLaunchDpc_cannotResolveIntent()187 public void maybeLaunchDpc_cannotResolveIntent() { 188 when(mUtils.canResolveIntentAsUser(any(), any(), anyInt())).thenReturn(false); 189 190 mProvisioningIntentProvider.maybeLaunchDpc(LEGACY_FLOW_PARAMS, 0, mUtils, mContext, 191 mProvisioningAnalyticsTracker, mPolicyComplianceUtils, mSettingsFacade); 192 193 verify(mContext, never()).startActivityAsUser(any(), any()); 194 verify(mProvisioningAnalyticsTracker, never()).logDpcSetupStarted(any(), any()); 195 } 196 197 @Test createProvisioningIntent_success()198 public void createProvisioningIntent_success() { 199 Intent intent = mProvisioningIntentProvider 200 .createProvisioningCompleteIntent(LEGACY_FLOW_PARAMS, 0, mUtils, mContext); 201 202 assertThat(intent.getAction()).isEqualTo(ACTION_PROFILE_PROVISIONING_COMPLETE); 203 assertThat(intent.getComponent()).isEqualTo(DEVICE_ADMIN_COMPONENT_NAME); 204 assertThat(intent.<PersistableBundle>getParcelableExtra( 205 EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE)).isEqualTo(ADMIN_EXTRAS_BUNDLE); 206 } 207 208 @Test createProvisioningIntent_cannotFindAdmin()209 public void createProvisioningIntent_cannotFindAdmin() 210 throws IllegalProvisioningArgumentException { 211 ProvisioningParams provisioningParams = new ProvisioningParams.Builder() 212 .setDeviceAdminPackageName(DEVICE_ADMIN_PACKAGE_NAME) 213 .setProvisioningAction(ACTION_PROVISION_MANAGED_PROFILE) 214 .build(); 215 when(mUtils.findDeviceAdmin(eq(DEVICE_ADMIN_PACKAGE_NAME), any(), any(), anyInt())) 216 .thenThrow(IllegalProvisioningArgumentException.class); 217 218 assertThat(mProvisioningIntentProvider.createProvisioningCompleteIntent( 219 provisioningParams, 0, mUtils, mContext)).isNull(); 220 } 221 makeProvisioningSuccessfulIntentResolvable()222 private void makeProvisioningSuccessfulIntentResolvable() { 223 when(mUtils.canResolveIntentAsUser(any(), any(Intent.class), anyInt())) 224 .thenAnswer(invocation -> { 225 Intent intentArgument = invocation.getArgument(/* index= */ 1); 226 return intentArgument.getAction().equals(ACTION_PROVISIONING_SUCCESSFUL); 227 }); 228 } 229 } 230