1 /* 2 * Copyright (C) 2020 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.parser; 18 19 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_FINANCED_DEVICE; 20 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE; 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_TRIGGER; 24 import static android.app.admin.DevicePolicyManager.FLAG_SUPPORTED_MODES_DEVICE_OWNER; 25 import static android.app.admin.DevicePolicyManager.FLAG_SUPPORTED_MODES_ORGANIZATION_OWNED; 26 import static android.app.admin.DevicePolicyManager.FLAG_SUPPORTED_MODES_PERSONALLY_OWNED; 27 import static android.app.admin.DevicePolicyManager.MIME_TYPE_PROVISIONING_NFC; 28 import static android.app.admin.DevicePolicyManager.PROVISIONING_MODE_FULLY_MANAGED_DEVICE; 29 import static android.app.admin.DevicePolicyManager.PROVISIONING_MODE_MANAGED_PROFILE; 30 import static android.app.admin.DevicePolicyManager.PROVISIONING_MODE_MANAGED_PROFILE_ON_PERSONAL_DEVICE; 31 import static android.app.admin.DevicePolicyManager.PROVISIONING_TRIGGER_CLOUD_ENROLLMENT; 32 import static android.app.admin.DevicePolicyManager.PROVISIONING_TRIGGER_PERSISTENT_DEVICE_OWNER; 33 import static android.app.admin.DevicePolicyManager.PROVISIONING_TRIGGER_QR_CODE; 34 import static android.app.admin.DevicePolicyManager.PROVISIONING_TRIGGER_UNSPECIFIED; 35 import static android.nfc.NfcAdapter.ACTION_NDEF_DISCOVERED; 36 import static android.provider.Settings.Secure.USER_SETUP_COMPLETE; 37 38 import static com.android.managedprovisioning.common.Globals.ACTION_PROVISION_MANAGED_DEVICE_SILENTLY; 39 import static com.android.managedprovisioning.model.ProvisioningParams.DEFAULT_EXTRA_PROVISIONING_SUPPORTED_MODES; 40 41 import static com.google.common.truth.Truth.assertThat; 42 43 import static org.robolectric.Shadows.shadowOf; 44 import static org.testng.Assert.assertThrows; 45 46 import android.content.Context; 47 import android.content.Intent; 48 import android.content.pm.PackageManager; 49 import android.provider.Settings; 50 51 import com.android.managedprovisioning.common.IllegalProvisioningArgumentException; 52 import com.android.managedprovisioning.common.SettingsFacade; 53 import com.android.managedprovisioning.common.Utils; 54 55 import org.junit.Before; 56 import org.junit.Test; 57 import org.junit.runner.RunWith; 58 import org.robolectric.RobolectricTestRunner; 59 import org.robolectric.RuntimeEnvironment; 60 61 /** 62 * Tests for {@link ParserUtils}. 63 */ 64 @RunWith(RobolectricTestRunner.class) 65 public class ParserUtilsTest { 66 67 private static final int INVALID_PROVISIONING_MODES = -1; 68 private static final int INVALID_PROVISIONING_MODE_COMBINATION = 69 FLAG_SUPPORTED_MODES_PERSONALLY_OWNED | FLAG_SUPPORTED_MODES_DEVICE_OWNER; 70 private final ParserUtils mParserUtils = new ParserUtils(); 71 private final SettingsFacade mSettingsFacade = new SettingsFacade(); 72 private final Context mContext = RuntimeEnvironment.application; 73 private final Utils mUtils = new Utils(); 74 75 @Before setUp()76 public void setUp() { 77 shadowOf(mContext.getPackageManager()) 78 .setSystemFeature(PackageManager.FEATURE_MANAGED_USERS, /* supported */ true); 79 } 80 81 @Test extractProvisioningTrigger_provisionManagedDeviceIntent_returnsUnspecified()82 public void extractProvisioningTrigger_provisionManagedDeviceIntent_returnsUnspecified() { 83 Intent intent = new Intent(ACTION_PROVISION_MANAGED_DEVICE); 84 85 assertThat(mParserUtils.extractProvisioningTrigger(intent)) 86 .isEqualTo(PROVISIONING_TRIGGER_UNSPECIFIED); 87 } 88 89 @Test extractProvisioningTrigger_provisionTrustedSourceIntentWithNoProvisioningTrigger_returnsUnspecified()90 public void extractProvisioningTrigger_provisionTrustedSourceIntentWithNoProvisioningTrigger_returnsUnspecified() { 91 Intent intent = new Intent(ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE); 92 93 assertThat(mParserUtils.extractProvisioningTrigger(intent)) 94 .isEqualTo(PROVISIONING_TRIGGER_UNSPECIFIED); 95 } 96 97 @Test 98 public void extractProvisioningTrigger_provisionTrustedSourceWithQrProvisioningTrigger_returnsQr()99 extractProvisioningTrigger_provisionTrustedSourceWithQrProvisioningTrigger_returnsQr() { 100 Intent intent = new Intent(ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE); 101 intent.putExtra(EXTRA_PROVISIONING_TRIGGER, PROVISIONING_TRIGGER_QR_CODE); 102 103 assertThat(mParserUtils.extractProvisioningTrigger(intent)) 104 .isEqualTo(PROVISIONING_TRIGGER_QR_CODE); 105 } 106 107 @Test extractProvisioningTrigger_provisionTrustedSourceWithCloudEnrollmentProvisioningTrigger_returnsCloudEnrollment()108 public void extractProvisioningTrigger_provisionTrustedSourceWithCloudEnrollmentProvisioningTrigger_returnsCloudEnrollment() { 109 Intent intent = new Intent(ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE); 110 intent.putExtra(EXTRA_PROVISIONING_TRIGGER, PROVISIONING_TRIGGER_CLOUD_ENROLLMENT); 111 112 assertThat(mParserUtils.extractProvisioningTrigger(intent)) 113 .isEqualTo(PROVISIONING_TRIGGER_CLOUD_ENROLLMENT); 114 } 115 116 @Test extractProvisioningTrigger_provisionTrustedSourceWithDeviceOwnerProvisioningTrigger_returnsPersistentDeviceOwner()117 public void extractProvisioningTrigger_provisionTrustedSourceWithDeviceOwnerProvisioningTrigger_returnsPersistentDeviceOwner() { 118 Intent intent = new Intent(ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE); 119 intent.putExtra(EXTRA_PROVISIONING_TRIGGER, PROVISIONING_TRIGGER_PERSISTENT_DEVICE_OWNER); 120 121 assertThat(mParserUtils.extractProvisioningTrigger(intent)) 122 .isEqualTo(PROVISIONING_TRIGGER_PERSISTENT_DEVICE_OWNER); 123 } 124 125 @Test 126 public void extractProvisioningAction_provisionManagedDeviceIntent_returnsProvisionManagedDevice()127 extractProvisioningAction_provisionManagedDeviceIntent_returnsProvisionManagedDevice() 128 throws IllegalProvisioningArgumentException { 129 Intent intent = new Intent(ACTION_PROVISION_MANAGED_DEVICE); 130 131 assertThat(mParserUtils.extractProvisioningAction(intent, mSettingsFacade, mContext)) 132 .isEqualTo(ACTION_PROVISION_MANAGED_DEVICE); 133 } 134 135 @Test 136 public void extractProvisioningAction_provisionManagedProfileIntent_returnsProvisionManagedProfile()137 extractProvisioningAction_provisionManagedProfileIntent_returnsProvisionManagedProfile() 138 throws IllegalProvisioningArgumentException { 139 Intent intent = new Intent(ACTION_PROVISION_MANAGED_PROFILE); 140 141 assertThat(mParserUtils.extractProvisioningAction(intent, mSettingsFacade, mContext)) 142 .isEqualTo(ACTION_PROVISION_MANAGED_PROFILE); 143 } 144 145 @Test 146 public void extractProvisioningAction_provisionFinancedDeviceIntent_returnsProvisionFinancedDevice()147 extractProvisioningAction_provisionFinancedDeviceIntent_returnsProvisionFinancedDevice() 148 throws IllegalProvisioningArgumentException { 149 Intent intent = new Intent(ACTION_PROVISION_FINANCED_DEVICE); 150 151 assertThat(mParserUtils.extractProvisioningAction(intent, mSettingsFacade, mContext)) 152 .isEqualTo(ACTION_PROVISION_FINANCED_DEVICE); 153 } 154 155 @Test 156 public void extractProvisioningAction_provisionManagedDeviceSilentlyIntent_returnsProvisionManagedDevice()157 extractProvisioningAction_provisionManagedDeviceSilentlyIntent_returnsProvisionManagedDevice() 158 throws IllegalProvisioningArgumentException { 159 Intent intent = new Intent(ACTION_PROVISION_MANAGED_DEVICE_SILENTLY); 160 161 assertThat(mParserUtils.extractProvisioningAction(intent, mSettingsFacade, mContext)) 162 .isEqualTo(ACTION_PROVISION_MANAGED_DEVICE); 163 } 164 165 @Test extractProvisioningAction_nfcIntent_returnsProvisionManagedDevice()166 public void extractProvisioningAction_nfcIntent_returnsProvisionManagedDevice() 167 throws IllegalProvisioningArgumentException { 168 Intent intent = new Intent(ACTION_NDEF_DISCOVERED); 169 intent.setType(MIME_TYPE_PROVISIONING_NFC); 170 171 assertThat(mParserUtils.extractProvisioningAction(intent, mSettingsFacade, mContext)) 172 .isEqualTo(ACTION_PROVISION_MANAGED_DEVICE); 173 } 174 175 @Test(expected = IllegalProvisioningArgumentException.class) testExtractProvisioningAction_nfcIntentWithNoMimeType_throwsException()176 public void testExtractProvisioningAction_nfcIntentWithNoMimeType_throwsException() 177 throws IllegalProvisioningArgumentException { 178 Intent intent = new Intent(ACTION_NDEF_DISCOVERED); 179 180 mParserUtils.extractProvisioningAction(intent, mSettingsFacade, mContext); 181 } 182 183 @Test(expected = IllegalProvisioningArgumentException.class) extractProvisioningAction_nfcIntentWithWrongMimeType_throwsException()184 public void extractProvisioningAction_nfcIntentWithWrongMimeType_throwsException() 185 throws IllegalProvisioningArgumentException { 186 Intent intent = new Intent(ACTION_NDEF_DISCOVERED); 187 intent.setType("wrongMimeType"); 188 189 mParserUtils.extractProvisioningAction(intent, mSettingsFacade, mContext); 190 } 191 192 @Test 193 public void extractProvisioningAction_trustedSourceDuringSetupWizard_returnsProvisionManagedDevice()194 extractProvisioningAction_trustedSourceDuringSetupWizard_returnsProvisionManagedDevice() 195 throws IllegalProvisioningArgumentException { 196 Intent intent = new Intent(ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE); 197 markDuringSetupWizard(); 198 199 assertThat(mParserUtils.extractProvisioningAction(intent, mSettingsFacade, mContext)) 200 .isEqualTo(ACTION_PROVISION_MANAGED_DEVICE); 201 } 202 203 @Test 204 public void extractProvisioningAction_trustedSourceAfterSetupWizard_returnsProvisionManagedProfile()205 extractProvisioningAction_trustedSourceAfterSetupWizard_returnsProvisionManagedProfile() 206 throws IllegalProvisioningArgumentException { 207 Intent intent = new Intent(ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE); 208 markAfterSetupWizard(); 209 210 assertThat(mParserUtils.extractProvisioningAction(intent, mSettingsFacade, mContext)) 211 .isEqualTo(ACTION_PROVISION_MANAGED_PROFILE); 212 } 213 214 @Test 215 public void getAllowedProvisioningModes_organizationOwned_returnsManagedProfileAndManagedDevice()216 getAllowedProvisioningModes_organizationOwned_returnsManagedProfileAndManagedDevice() { 217 assertThat(mParserUtils.getAllowedProvisioningModes(mContext, 218 FLAG_SUPPORTED_MODES_ORGANIZATION_OWNED, mUtils)).containsExactly( 219 PROVISIONING_MODE_MANAGED_PROFILE, 220 PROVISIONING_MODE_FULLY_MANAGED_DEVICE); 221 } 222 223 @Test 224 public void getAllowedProvisioningModes_personallyOwned_returnsManagedProfileOnly()225 getAllowedProvisioningModes_personallyOwned_returnsManagedProfileOnly() { 226 assertThat(mParserUtils.getAllowedProvisioningModes(mContext, 227 FLAG_SUPPORTED_MODES_PERSONALLY_OWNED, mUtils)).containsExactly( 228 PROVISIONING_MODE_MANAGED_PROFILE); 229 } 230 231 @Test getAllowedProvisioningModes_organizationAndPersonallyOwned_returnsManagedProfileManagedDevicePersonalManagedProfile()232 public void getAllowedProvisioningModes_organizationAndPersonallyOwned_returnsManagedProfileManagedDevicePersonalManagedProfile() { 233 assertThat(mParserUtils.getAllowedProvisioningModes(mContext, 234 FLAG_SUPPORTED_MODES_ORGANIZATION_OWNED 235 | FLAG_SUPPORTED_MODES_PERSONALLY_OWNED, mUtils)).containsExactly( 236 PROVISIONING_MODE_MANAGED_PROFILE, 237 PROVISIONING_MODE_FULLY_MANAGED_DEVICE, 238 PROVISIONING_MODE_MANAGED_PROFILE_ON_PERSONAL_DEVICE); 239 } 240 241 @Test getAllowedProvisioningModes_deviceOwner_returnsManagedDevice()242 public void getAllowedProvisioningModes_deviceOwner_returnsManagedDevice() { 243 assertThat(mParserUtils.getAllowedProvisioningModes(mContext, 244 FLAG_SUPPORTED_MODES_DEVICE_OWNER, mUtils)).containsExactly( 245 PROVISIONING_MODE_FULLY_MANAGED_DEVICE); 246 } 247 248 @Test getAllowedProvisioningModes_invalidValue_throwsException()249 public void getAllowedProvisioningModes_invalidValue_throwsException() { 250 assertThrows( 251 IllegalArgumentException.class, 252 () -> mParserUtils 253 .getAllowedProvisioningModes(mContext, INVALID_PROVISIONING_MODES, mUtils)); 254 } 255 256 @Test getAllowedProvisioningModes_invalidBinaryCombination_throwsException()257 public void getAllowedProvisioningModes_invalidBinaryCombination_throwsException() { 258 assertThrows( 259 IllegalArgumentException.class, 260 () -> mParserUtils.getAllowedProvisioningModes(mContext, 261 INVALID_PROVISIONING_MODE_COMBINATION, mUtils)); 262 } 263 264 @Test 265 public void getAllowedProvisioningModes_organizationOwnedAndManagedUsersNotSupported_returnsManagedDeviceOnly()266 getAllowedProvisioningModes_organizationOwnedAndManagedUsersNotSupported_returnsManagedDeviceOnly() { 267 shadowOf(mContext.getPackageManager()) 268 .setSystemFeature(PackageManager.FEATURE_MANAGED_USERS, /* supported = */ false); 269 270 assertThat(mParserUtils.getAllowedProvisioningModes(mContext, 271 FLAG_SUPPORTED_MODES_ORGANIZATION_OWNED, mUtils)).containsExactly( 272 PROVISIONING_MODE_FULLY_MANAGED_DEVICE); 273 } 274 275 @Test 276 public void getAllowedProvisioningModes_personallyOwnedAndManagedUsersNotSupported_throwsException()277 getAllowedProvisioningModes_personallyOwnedAndManagedUsersNotSupported_throwsException() { 278 shadowOf(mContext.getPackageManager()) 279 .setSystemFeature(PackageManager.FEATURE_MANAGED_USERS, /* supported */ false); 280 281 assertThrows( 282 IllegalArgumentException.class, 283 () -> mParserUtils 284 .getAllowedProvisioningModes(mContext, 285 FLAG_SUPPORTED_MODES_PERSONALLY_OWNED, mUtils)); 286 } 287 288 @Test getAllowedProvisioningModes_defaultValue_returnsEmptyArray()289 public void getAllowedProvisioningModes_defaultValue_returnsEmptyArray() { 290 assertThat(mParserUtils.getAllowedProvisioningModes(mContext, 291 DEFAULT_EXTRA_PROVISIONING_SUPPORTED_MODES, mUtils)).isEmpty(); 292 } 293 294 @Test validateSupportedModes_personallyOwned_doesNothing()295 public void validateSupportedModes_personallyOwned_doesNothing() { 296 mParserUtils.getAllowedProvisioningModes( 297 mContext, FLAG_SUPPORTED_MODES_PERSONALLY_OWNED, mUtils); 298 } 299 300 @Test validateSupportedModes_organizationOwned_doesNothing()301 public void validateSupportedModes_organizationOwned_doesNothing() { 302 mParserUtils.getAllowedProvisioningModes( 303 mContext, FLAG_SUPPORTED_MODES_ORGANIZATION_OWNED, mUtils); 304 } 305 306 @Test validateSupportedModes_deviceOwner_doesNothing()307 public void validateSupportedModes_deviceOwner_doesNothing() { 308 mParserUtils.getAllowedProvisioningModes( 309 mContext, FLAG_SUPPORTED_MODES_DEVICE_OWNER, mUtils); 310 } 311 312 @Test validateSupportedModes_personalAndOrganizationOwned_doesNothing()313 public void validateSupportedModes_personalAndOrganizationOwned_doesNothing() { 314 mParserUtils.getAllowedProvisioningModes( 315 mContext, 316 FLAG_SUPPORTED_MODES_ORGANIZATION_OWNED | FLAG_SUPPORTED_MODES_PERSONALLY_OWNED, 317 mUtils); 318 } 319 320 @Test validateSupportedModes_invalidValue_throwsException()321 public void validateSupportedModes_invalidValue_throwsException() { 322 assertThrows( 323 IllegalArgumentException.class, 324 () -> mParserUtils 325 .getAllowedProvisioningModes(mContext, INVALID_PROVISIONING_MODES, mUtils)); 326 } 327 328 @Test validateSupportedModes_invalidBinaryCombination_throwsException()329 public void validateSupportedModes_invalidBinaryCombination_throwsException() { 330 assertThrows( 331 IllegalArgumentException.class, 332 () -> mParserUtils.validateSupportedModes(INVALID_PROVISIONING_MODE_COMBINATION)); 333 } 334 markDuringSetupWizard()335 private boolean markDuringSetupWizard() { 336 return Settings.Secure.putInt(mContext.getContentResolver(), USER_SETUP_COMPLETE, 0); 337 } 338 markAfterSetupWizard()339 private boolean markAfterSetupWizard() { 340 return Settings.Secure.putInt(mContext.getContentResolver(), USER_SETUP_COMPLETE, 1); 341 } 342 } 343