1 /* 2 * Copyright (C) 2015 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.cts.devicepolicy; 18 19 import static com.android.cts.devicepolicy.metrics.DevicePolicyEventLogVerifier.assertMetricsLogged; 20 21 import static org.junit.Assert.fail; 22 23 import android.app.admin.flags.Flags; 24 import android.platform.test.annotations.FlakyTest; 25 import android.platform.test.annotations.LargeTest; 26 import android.platform.test.annotations.RequiresFlagsEnabled; 27 import android.platform.test.flag.junit.CheckFlagsRule; 28 import android.platform.test.flag.junit.host.HostFlagsValueProvider; 29 import android.stats.devicepolicy.EventId; 30 31 import com.android.cts.devicepolicy.DeviceAdminFeaturesCheckerRule.IgnoreOnHeadlessSystemUserMode; 32 import com.android.cts.devicepolicy.DeviceAdminFeaturesCheckerRule.TemporarilyIgnoreOnHeadlessSystemUserMode; 33 import com.android.cts.devicepolicy.metrics.DevicePolicyEventWrapper; 34 import com.android.tradefed.device.DeviceNotAvailableException; 35 import com.android.tradefed.log.LogUtil.CLog; 36 37 import org.junit.Ignore; 38 import org.junit.Rule; 39 import org.junit.Test; 40 41 import java.io.FileNotFoundException; 42 import java.util.Collections; 43 import java.util.HashMap; 44 import java.util.Map; 45 46 /** 47 * Set of tests for device owner use cases that also apply to profile owners. 48 * Tests that should be run identically in both cases are added in DeviceAndProfileOwnerTest. 49 */ 50 public final class MixedDeviceOwnerTest extends DeviceAndProfileOwnerTest { 51 52 private static final String ARG_SECURITY_LOGGING_BATCH_NUMBER = "batchNumber"; 53 private static final int SECURITY_EVENTS_BATCH_SIZE = 100; 54 55 private boolean mDeviceOwnerSet; 56 57 @Rule 58 public final CheckFlagsRule mCheckFlagsRule = 59 HostFlagsValueProvider.createCheckFlagsRule(this::getDevice); 60 61 @Override setUp()62 public void setUp() throws Exception { 63 super.setUp(); 64 65 mUserId = mPrimaryUserId; 66 67 CLog.i("%s.setUp(): mUserId=%d, mPrimaryUserId=%d, mInitialUserId=%d, " 68 + "mDeviceOwnerUserId=%d", getClass(), mUserId, mPrimaryUserId, mInitialUserId, 69 mDeviceOwnerUserId); 70 71 installDeviceOwnerApp(DEVICE_ADMIN_APK); 72 mDeviceOwnerSet = setDeviceOwner(DEVICE_ADMIN_COMPONENT_FLATTENED, mDeviceOwnerUserId, 73 /*expectFailure= */ false); 74 75 if (!mDeviceOwnerSet) { 76 removeDeviceOwnerAdmin(DEVICE_ADMIN_COMPONENT_FLATTENED); 77 getDevice().uninstallPackage(DEVICE_ADMIN_PKG); 78 fail("Failed to set device owner on user " + mDeviceOwnerUserId); 79 } 80 } 81 82 @Override tearDown()83 public void tearDown() throws Exception { 84 if (mDeviceOwnerSet) { 85 removeDeviceOwnerAdmin(DEVICE_ADMIN_COMPONENT_FLATTENED); 86 } 87 88 super.tearDown(); 89 } 90 91 @Override installAppPermissionAppAsUser()92 protected void installAppPermissionAppAsUser() 93 throws FileNotFoundException, DeviceNotAvailableException { 94 super.installAppPermissionAppAsUser(); 95 96 if (isHeadlessSystemUserMode()) { 97 installAppPermissionAppAsUser(mDeviceOwnerUserId); 98 } 99 } 100 101 @Test 102 @IgnoreOnHeadlessSystemUserMode(reason = "CreateAndManageUsers is blocked on headless single " 103 + "user mode") testLockTask_unaffiliatedUser()104 public void testLockTask_unaffiliatedUser() throws Exception { 105 assumeCanCreateAdditionalUsers(1); 106 107 final int userId = createSecondaryUserAsProfileOwner(); 108 runDeviceTestsAsUser( 109 DEVICE_ADMIN_PKG, 110 ".AffiliationTest", 111 "testLockTaskMethodsThrowExceptionIfUnaffiliated", 112 userId); 113 114 setUserAsAffiliatedUserToPrimary(userId); 115 runDeviceTestsAsUser( 116 DEVICE_ADMIN_PKG, 117 ".AffiliationTest", 118 "testSetLockTaskPackagesClearedIfUserBecomesUnaffiliated", 119 userId); 120 } 121 122 @Override 123 @Test 124 @TemporarilyIgnoreOnHeadlessSystemUserMode(bugId = "218408549", 125 reason = "Will be migrated to new test infra") testDelegationCertSelection()126 public void testDelegationCertSelection() throws Exception { 127 super.testDelegationCertSelection(); 128 } 129 130 @TemporarilyIgnoreOnHeadlessSystemUserMode(bugId = "218408549", 131 reason = "Will be migrated to new test infra") 132 @Test testDelegatedCertInstallerDeviceIdAttestation()133 public void testDelegatedCertInstallerDeviceIdAttestation() throws Exception { 134 setUpDelegatedCertInstallerAndRunTests(() -> 135 runDeviceTestsAsUser("com.android.cts.certinstaller", 136 ".DelegatedDeviceIdAttestationTest", 137 "testGenerateKeyPairWithDeviceIdAttestationExpectingSuccess", mUserId)); 138 } 139 140 @TemporarilyIgnoreOnHeadlessSystemUserMode(bugId = "218408549", 141 reason = "Will be migrated to new test infra") 142 @Override testDelegatedCertInstaller()143 public void testDelegatedCertInstaller() throws Exception { 144 super.testDelegatedCertInstaller(); 145 } 146 147 @Test testLockScreenInfo()148 public void testLockScreenInfo() throws Exception { 149 executeDeviceTestClass(".LockScreenInfoTest"); 150 151 assertMetricsLogged(getDevice(), () -> { 152 executeDeviceTestMethod(".LockScreenInfoTest", "testSetAndGetLockInfo"); 153 }, new DevicePolicyEventWrapper.Builder(EventId.SET_DEVICE_OWNER_LOCK_SCREEN_INFO_VALUE) 154 .setAdminPackageName(DEVICE_ADMIN_PKG) 155 .build()); 156 } 157 158 @Test testCommonCriteriaMode()159 public void testCommonCriteriaMode() throws Exception { 160 executeDeviceTestClass(".CommonCriteriaModeTest"); 161 } 162 163 @LargeTest 164 @Test 165 @Ignore("b/145932189") testSystemUpdatePolicy()166 public void testSystemUpdatePolicy() throws Exception { 167 executeDeviceTestClass(".systemupdate.SystemUpdatePolicyTest"); 168 } 169 170 @Test testInstallUpdate()171 public void testInstallUpdate() throws Exception { 172 pushUpdateFileToDevice("notZip.zi"); 173 pushUpdateFileToDevice("empty.zip"); 174 pushUpdateFileToDevice("wrongPayload.zip"); 175 pushUpdateFileToDevice("wrongHash.zip"); 176 pushUpdateFileToDevice("wrongSize.zip"); 177 178 executeInstallUpdateTest(/* testName= */ null); 179 } 180 181 @Test testInstallUpdateLogged()182 public void testInstallUpdateLogged() throws Exception { 183 assumeIsDeviceAb(); 184 185 pushUpdateFileToDevice("wrongHash.zip"); 186 assertMetricsLogged(getDevice(), () -> { 187 executeInstallUpdateTest("testInstallUpdate_failWrongHash"); 188 }, new DevicePolicyEventWrapper.Builder(EventId.INSTALL_SYSTEM_UPDATE_VALUE) 189 .setAdminPackageName(DEVICE_ADMIN_PKG) 190 .setBoolean(/* isDeviceAb */ true) 191 .build(), 192 new DevicePolicyEventWrapper.Builder(EventId.INSTALL_SYSTEM_UPDATE_ERROR_VALUE) 193 .setInt(UPDATE_ERROR_UPDATE_FILE_INVALID) 194 .build()); 195 } 196 executeInstallUpdateTest(String testName)197 private void executeInstallUpdateTest(String testName) throws Exception { 198 // This test must run on system user as it calls installSystemUpdate(), which takes a 199 // Runnable callback (InstallSystemUpdateCallback) and hence it cannot be easily passed 200 // around through IPC (on headless system user mode). 201 executeDeviceTestMethodOnDeviceOwnerUser(".systemupdate.InstallUpdateTest", testName); 202 } 203 204 // This test sometimes fail on headless system user mode because the DO app doesn't have 205 // INTERACT_ACROSS_USERS to use DpmWrapper - given that it will be refactored to use the new 206 // test infra, it's not worth to figure out why... 207 @FlakyTest(bugId = 137088260) 208 @Test testSecurityLoggingWithSingleUser()209 public void testSecurityLoggingWithSingleUser() throws Exception { 210 // Backup stay awake setting because testGenerateLogs() will turn it off. 211 final String stayAwake = getDevice().getSetting("global", "stay_on_while_plugged_in"); 212 try { 213 // Turn logging on. 214 executeDeviceTestMethod(".SecurityLoggingTest", "testEnablingSecurityLogging"); 215 // Reboot to ensure ro.device_owner is set to true in logd and logging is on. 216 rebootAndWaitUntilReady(); 217 waitForUserUnlock(mUserId); 218 219 // Generate various types of events on device side and check that they are logged. 220 executeDeviceTestMethod(".SecurityLoggingTest", "testGenerateLogs"); 221 getDevice().executeShellCommand("whoami"); // Generate adb command securty event 222 executeDeviceTestMethod(".SecurityLoggingTest", "testVerifyGeneratedLogs"); 223 224 // Reboot the device, so the security event ids are reset. 225 rebootAndWaitUntilReady(); 226 227 // Verify event ids are consistent across a consecutive batch. 228 for (int batchNumber = 0; batchNumber < 3; batchNumber++) { 229 generateTestSecurityLogs(); 230 executeDeviceTestMethod(".SecurityLoggingTest", "testVerifyLogIds", 231 Collections.singletonMap(ARG_SECURITY_LOGGING_BATCH_NUMBER, 232 Integer.toString(batchNumber))); 233 } 234 235 // Immediately attempting to fetch events again should fail. 236 executeDeviceTestMethod(".SecurityLoggingTest", 237 "testSecurityLoggingRetrievalRateLimited"); 238 } finally { 239 // Turn logging off. 240 executeDeviceTestMethod(".SecurityLoggingTest", "testDisablingSecurityLogging"); 241 // Restore stay awake setting. 242 if (stayAwake != null) { 243 getDevice().setSetting("global", "stay_on_while_plugged_in", stayAwake); 244 } 245 } 246 } 247 248 @Test testSecurityLoggingEnabledLogged()249 public void testSecurityLoggingEnabledLogged() throws Exception { 250 assertMetricsLogged(getDevice(), () -> { 251 executeDeviceTestMethod(".SecurityLoggingTest", "testEnablingSecurityLogging"); 252 executeDeviceTestMethod(".SecurityLoggingTest", "testDisablingSecurityLogging"); 253 }, new DevicePolicyEventWrapper.Builder(EventId.SET_SECURITY_LOGGING_ENABLED_VALUE) 254 .setAdminPackageName(DEVICE_ADMIN_PKG) 255 .setBoolean(true) 256 .build(), 257 new DevicePolicyEventWrapper.Builder(EventId.SET_SECURITY_LOGGING_ENABLED_VALUE) 258 .setAdminPackageName(DEVICE_ADMIN_PKG) 259 .setBoolean(false) 260 .build()); 261 } 262 263 @Test testSecurityLoggingWithTwoUsers()264 public void testSecurityLoggingWithTwoUsers() throws Exception { 265 assumeCanCreateAdditionalUsers(1); 266 267 final int userId = createUser(); 268 try { 269 // The feature can be enabled, but in a "paused" state. Attempting to retrieve logs 270 // should throw security exception. 271 executeDeviceTestMethod(".SecurityLoggingTest", "testEnablingSecurityLogging"); 272 executeDeviceTestMethod(".SecurityLoggingTest", 273 "testRetrievingSecurityLogsThrowsSecurityException"); 274 executeDeviceTestMethod(".SecurityLoggingTest", 275 "testRetrievingPreviousSecurityLogsThrowsSecurityException"); 276 } finally { 277 removeUser(userId); 278 executeDeviceTestMethod(".SecurityLoggingTest", "testDisablingSecurityLogging"); 279 } 280 } 281 282 @Test 283 @RequiresFlagsEnabled(Flags.FLAG_HEADLESS_DEVICE_OWNER_DELEGATE_SECURITY_LOGGING_BUG_FIX) testSecurityLoggingDelegate()284 public void testSecurityLoggingDelegate() throws Exception { 285 installAppAsUser(DELEGATE_APP_APK, mDeviceOwnerUserId); 286 try { 287 // Test that the delegate cannot access the logs already 288 runDeviceTestsAsUser(DELEGATE_APP_PKG, ".SecurityLoggingDelegateTest", 289 "testCannotAccessApis", mDeviceOwnerUserId); 290 291 // Set security logging delegate 292 executeDeviceTestMethodOnDeviceOwnerUser(".SecurityLoggingTest", 293 "testSetDelegateScope_delegationSecurityLogging"); 294 295 runSecurityLoggingTests(DELEGATE_APP_PKG, ".SecurityLoggingDelegateTest"); 296 } finally { 297 // Remove security logging delegate 298 executeDeviceTestMethodOnDeviceOwnerUser(".SecurityLoggingTest", 299 "testSetDelegateScope_noDelegation"); 300 } 301 } 302 runSecurityLoggingTests(String packageName, String testClassName)303 private void runSecurityLoggingTests(String packageName, String testClassName) 304 throws Exception { 305 int userId = mDeviceOwnerUserId; 306 try { 307 // Turn logging on. 308 runDeviceTestsAsUser(packageName, testClassName, "testEnablingSecurityLogging", userId); 309 // Reboot to ensure ro.organization_owned is set to true in logd and logging is on. 310 rebootAndWaitUntilReady(); 311 waitForUserUnlock(userId); 312 313 // Generate various types of events on device side and check that they are logged. 314 runDeviceTestsAsUser(packageName, testClassName, "testGenerateLogs", userId); 315 runDeviceTestsAsUser(packageName, testClassName, "testVerifyGeneratedLogs", userId); 316 317 // Immediately attempting to fetch events again should fail. 318 runDeviceTestsAsUser(packageName, testClassName, 319 "testSecurityLoggingRetrievalRateLimited", userId); 320 } finally { 321 // Turn logging off. 322 runDeviceTestsAsUser(packageName, testClassName, 323 "testDisablingSecurityLogging", userId); 324 } 325 } 326 327 @Override 328 @Test testAdminControlOverSensorPermissionGrantsDefault()329 public void testAdminControlOverSensorPermissionGrantsDefault() throws Exception { 330 // In Device Owner mode, by default, admin should be able to grant sensors-related 331 // permissions. 332 executeDeviceTestMethod(".SensorPermissionGrantTest", 333 "testAdminCanGrantSensorsPermissions"); 334 } 335 336 //TODO(b/180413140) Investigate why the test fails on DO mode. 337 @Override 338 @Test testPermissionPrompts()339 public void testPermissionPrompts() throws Exception { 340 } 341 342 343 @Override 344 @LargeTest 345 @Test 346 @IgnoreOnHeadlessSystemUserMode(reason = "Headless system user doesn't have UI") testPackageInstallUserRestrictions()347 public void testPackageInstallUserRestrictions() throws Exception { 348 super.testPackageInstallUserRestrictions(); 349 } 350 351 @Override 352 @Test 353 @IgnoreOnHeadlessSystemUserMode(reason = "Headless system user doesn't launch activities") testSuspendPackage()354 public void testSuspendPackage() throws Exception { 355 super.testSuspendPackage(); 356 } 357 358 @Override 359 @Test 360 @IgnoreOnHeadlessSystemUserMode(reason = "Headless system user doesn't launch activities") testSuspendPackageWithPackageManager()361 public void testSuspendPackageWithPackageManager() throws Exception { 362 super.testSuspendPackageWithPackageManager(); 363 } 364 365 @Override 366 @Test 367 @IgnoreOnHeadlessSystemUserMode(reason = "Headless system user doesn't have credentials") testGetPasswordExpiration()368 public void testGetPasswordExpiration() throws Exception { 369 super.testGetPasswordExpiration(); 370 } 371 372 @Override 373 @Test 374 @IgnoreOnHeadlessSystemUserMode(reason = "Headless system user doesn't have credentials") testPasswordExpiration()375 public void testPasswordExpiration() throws Exception { 376 super.testPasswordExpiration(); 377 } 378 379 @Override 380 @Test 381 @IgnoreOnHeadlessSystemUserMode(reason = "Headless system user doesn't launch activities") testDisallowAutofill_allowed()382 public void testDisallowAutofill_allowed() throws Exception { 383 super.testDisallowAutofill_allowed(); 384 } 385 386 @Override 387 @Test 388 @IgnoreOnHeadlessSystemUserMode(reason = "Headless system user doesn't launch activities") testPermissionAppUpdate()389 public void testPermissionAppUpdate() throws Exception { 390 super.testPermissionAppUpdate(); 391 } 392 393 @Override 394 @Test 395 @IgnoreOnHeadlessSystemUserMode(reason = "Headless system user doesn't launch activities") testPermissionPolicy()396 public void testPermissionPolicy() throws Exception { 397 super.testPermissionPolicy(); 398 } 399 400 @Override 401 @Test 402 @IgnoreOnHeadlessSystemUserMode(reason = "Headless system user doesn't launch activities") testPermissionGrantOfDisallowedPermissionWhileOtherPermIsGranted()403 public void testPermissionGrantOfDisallowedPermissionWhileOtherPermIsGranted() 404 throws Exception { 405 super.testPermissionGrantOfDisallowedPermissionWhileOtherPermIsGranted(); 406 } 407 408 @Ignore("b/330134976") 409 @LargeTest 410 @Test testLockTaskCantBeInterrupted()411 public void testLockTaskCantBeInterrupted() throws Exception { 412 try { 413 // Just start kiosk mode 414 executeDeviceTestMethod( 415 ".LockTaskHostDrivenTest", "testStartLockTask_noAsserts"); 416 417 // Check that kiosk mode is working and can't be interrupted 418 executeDeviceTestMethod(".LockTaskHostDrivenTest", 419 "testLockTaskIsActiveAndCantBeInterrupted"); 420 } finally { 421 executeDeviceTestMethod(".LockTaskHostDrivenTest", "testCleanupLockTask_noAsserts"); 422 } 423 } 424 425 426 @Override installDelegateApp()427 protected void installDelegateApp() throws Exception { 428 // TODO(b/176993670): must call installDeviceOwnerApp() - even though it's not one - so 429 // the permissions required to use DpmWrapper are set on headless system user mode 430 installDeviceOwnerApp(DELEGATE_APP_APK); 431 } 432 433 @Override runDeviceTestsAsUser(String pkgName, String testClassName, String testName, int userId, Map<String, String> params)434 protected void runDeviceTestsAsUser(String pkgName, String testClassName, String testName, 435 int userId, Map<String, String> params) throws DeviceNotAvailableException { 436 Map<String, String> newParams = new HashMap(params); 437 Map<String, String> doParams = getParamsForDeviceOwnerTest(); 438 CLog.d("runDeviceTestsAsUser(): adding device owner params (%s)", doParams); 439 newParams.putAll(doParams); 440 super.runDeviceTestsAsUser( 441 pkgName, testClassName, testName, userId, newParams); 442 } 443 444 @Override getAdditionalExtrasForSetPolicyActivity()445 protected String getAdditionalExtrasForSetPolicyActivity() { 446 return " --es extra-admin-type DeviceOwner"; 447 } 448 449 @Override getUserIdForAlwaysOnVpnTests()450 protected int getUserIdForAlwaysOnVpnTests() { 451 // Running on current user on headless system user would require too many hacky changes on 452 // DpmWrapper / VpnTestHelper such as providing a ConnectivityManager and properly waiting 453 // for broadcasts 454 return mDeviceOwnerUserId; 455 } 456 457 @Override executeDeviceTestMethod(String className, String testName, Map<String, String> params)458 protected void executeDeviceTestMethod(String className, String testName, 459 Map<String, String> params) throws Exception { 460 runDeviceTestsAsUser(DEVICE_ADMIN_PKG, className, testName, mUserId, params); 461 } 462 executeDeviceTestMethodOnDeviceOwnerUser(String className, String testName)463 private void executeDeviceTestMethodOnDeviceOwnerUser(String className, String testName) 464 throws Exception { 465 executeDeviceTestMethod(className, testName, mDeviceOwnerUserId, 466 /* params= */ new HashMap<>()); 467 } 468 generateTestSecurityLogs()469 private void generateTestSecurityLogs() throws Exception { 470 // Trigger security events of type TAG_ADB_SHELL_CMD. 471 for (int i = 0; i < SECURITY_EVENTS_BATCH_SIZE; i++) { 472 getDevice().executeShellCommand("echo just_testing_" + i); 473 } 474 } 475 createSecondaryUserAsProfileOwner()476 private int createSecondaryUserAsProfileOwner() throws Exception { 477 final int userId = createUserAndWaitStart(); 478 installAppAsUser(INTENT_RECEIVER_APK, userId); 479 installAppAsUser(DEVICE_ADMIN_APK, userId); 480 setProfileOwnerOrFail(DEVICE_ADMIN_COMPONENT_FLATTENED, userId); 481 return userId; 482 } 483 setUserAsAffiliatedUserToPrimary(int userId)484 private void setUserAsAffiliatedUserToPrimary(int userId) throws Exception { 485 // Setting the same affiliation ids on both users 486 runDeviceTestsAsUser( 487 DEVICE_ADMIN_PKG, ".AffiliationTest", "testSetAffiliationId1", mPrimaryUserId); 488 runDeviceTestsAsUser( 489 DEVICE_ADMIN_PKG, ".AffiliationTest", "testSetAffiliationId1", userId); 490 } 491 } 492