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 package com.android.server.devicepolicy; 17 18 import static android.app.AppOpsManager.MODE_ALLOWED; 19 import static android.app.AppOpsManager.MODE_DEFAULT; 20 import static android.app.AppOpsManager.OP_ACTIVATE_VPN; 21 import static android.app.Notification.EXTRA_TEXT; 22 import static android.app.Notification.EXTRA_TITLE; 23 import static android.app.admin.DevicePolicyManager.ACTION_CHECK_POLICY_COMPLIANCE; 24 import static android.app.admin.DevicePolicyManager.DELEGATION_APP_RESTRICTIONS; 25 import static android.app.admin.DevicePolicyManager.DELEGATION_CERT_INSTALL; 26 import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_DEFAULT; 27 import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_FINANCED; 28 import static android.app.admin.DevicePolicyManager.ID_TYPE_BASE_INFO; 29 import static android.app.admin.DevicePolicyManager.ID_TYPE_IMEI; 30 import static android.app.admin.DevicePolicyManager.ID_TYPE_MEID; 31 import static android.app.admin.DevicePolicyManager.ID_TYPE_SERIAL; 32 import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_HIGH; 33 import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_LOW; 34 import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_MEDIUM; 35 import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE; 36 import static android.app.admin.DevicePolicyManager.PRIVATE_DNS_SET_NO_ERROR; 37 import static android.app.admin.DevicePolicyManager.WIPE_EUICC; 38 import static android.app.admin.PasswordMetrics.computeForPasswordOrPin; 39 import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE; 40 import static android.net.InetAddresses.parseNumericAddress; 41 42 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE; 43 import static com.android.internal.widget.LockPatternUtils.EscrowTokenStateChangeCallback; 44 import static com.android.server.devicepolicy.DevicePolicyManagerService.ACTION_PROFILE_OFF_DEADLINE; 45 import static com.android.server.devicepolicy.DevicePolicyManagerService.ACTION_TURN_PROFILE_ON_NOTIFICATION; 46 import static com.android.server.devicepolicy.DpmMockContext.CALLER_USER_HANDLE; 47 import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME; 48 import static com.android.server.testutils.TestUtils.assertExpectException; 49 50 import static com.google.common.truth.Truth.assertThat; 51 import static com.google.common.truth.Truth.assertWithMessage; 52 53 import static org.junit.Assert.fail; 54 import static org.junit.Assume.assumeTrue; 55 import static org.mockito.Matchers.any; 56 import static org.mockito.Matchers.anyBoolean; 57 import static org.mockito.Matchers.anyInt; 58 import static org.mockito.Matchers.anyLong; 59 import static org.mockito.Matchers.anyObject; 60 import static org.mockito.Matchers.anyString; 61 import static org.mockito.Matchers.eq; 62 import static org.mockito.Matchers.isNull; 63 import static org.mockito.Mockito.clearInvocations; 64 import static org.mockito.Mockito.doAnswer; 65 import static org.mockito.Mockito.doReturn; 66 import static org.mockito.Mockito.never; 67 import static org.mockito.Mockito.nullable; 68 import static org.mockito.Mockito.reset; 69 import static org.mockito.Mockito.timeout; 70 import static org.mockito.Mockito.times; 71 import static org.mockito.Mockito.verify; 72 import static org.mockito.Mockito.verifyNoMoreInteractions; 73 import static org.mockito.Mockito.verifyZeroInteractions; 74 import static org.mockito.Mockito.when; 75 import static org.mockito.hamcrest.MockitoHamcrest.argThat; 76 import static org.testng.Assert.assertThrows; 77 78 import static java.util.Collections.emptyList; 79 80 import android.Manifest.permission; 81 import android.app.Activity; 82 import android.app.AppOpsManager; 83 import android.app.Notification; 84 import android.app.PendingIntent; 85 import android.app.admin.DeviceAdminReceiver; 86 import android.app.admin.DevicePolicyManager; 87 import android.app.admin.DevicePolicyManagerInternal; 88 import android.app.admin.DevicePolicyManagerLiteInternal; 89 import android.app.admin.FactoryResetProtectionPolicy; 90 import android.app.admin.PasswordMetrics; 91 import android.app.admin.SystemUpdatePolicy; 92 import android.content.BroadcastReceiver; 93 import android.content.ComponentName; 94 import android.content.Intent; 95 import android.content.pm.ApplicationInfo; 96 import android.content.pm.PackageInfo; 97 import android.content.pm.PackageManager; 98 import android.content.pm.ResolveInfo; 99 import android.content.pm.StringParceledListSlice; 100 import android.content.pm.UserInfo; 101 import android.graphics.Color; 102 import android.hardware.usb.UsbManager; 103 import android.net.ConnectivityManager; 104 import android.net.Uri; 105 import android.os.Build; 106 import android.os.Build.VERSION_CODES; 107 import android.os.Bundle; 108 import android.os.Process; 109 import android.os.UserHandle; 110 import android.os.UserManager; 111 import android.platform.test.annotations.FlakyTest; 112 import android.platform.test.annotations.Presubmit; 113 import android.provider.Settings; 114 import android.security.KeyChain; 115 import android.security.keystore.AttestationUtils; 116 import android.telephony.TelephonyManager; 117 import android.telephony.data.ApnSetting; 118 import android.test.MoreAsserts; // TODO(b/171932723): replace by Truth 119 import android.util.ArraySet; 120 import android.util.Log; 121 import android.util.Pair; 122 123 import androidx.test.filters.SmallTest; 124 125 import com.android.internal.R; 126 import com.android.internal.messages.nano.SystemMessageProto; 127 import com.android.internal.widget.LockPatternUtils; 128 import com.android.internal.widget.LockscreenCredential; 129 import com.android.server.LocalServices; 130 import com.android.server.SystemService; 131 import com.android.server.devicepolicy.DevicePolicyManagerService.RestrictionsListener; 132 133 import org.hamcrest.BaseMatcher; 134 import org.hamcrest.Description; 135 import org.hamcrest.Matcher; 136 import org.junit.After; 137 import org.junit.Before; 138 import org.junit.Test; 139 import org.mockito.Mockito; 140 import org.mockito.internal.util.collections.Sets; 141 import org.mockito.stubbing.Answer; 142 143 import java.io.File; 144 import java.net.InetSocketAddress; 145 import java.net.Proxy; 146 import java.util.ArrayList; 147 import java.util.Arrays; 148 import java.util.Collections; 149 import java.util.HashMap; 150 import java.util.List; 151 import java.util.Map; 152 import java.util.Set; 153 import java.util.concurrent.TimeUnit; 154 155 /** 156 * Tests for DevicePolicyManager( and DevicePolicyManagerService). 157 * 158 * <p>Run this test with: 159 * 160 * {@code atest FrameworksServicesTests:com.android.server.devicepolicy.DevicePolicyManagerTest} 161 * 162 */ 163 @SmallTest 164 @Presubmit 165 public class DevicePolicyManagerTest extends DpmTestBase { 166 167 private static final String TAG = DevicePolicyManagerTest.class.getSimpleName(); 168 169 private static final List<String> OWNER_SETUP_PERMISSIONS = Arrays.asList( 170 permission.MANAGE_DEVICE_ADMINS, permission.MANAGE_PROFILE_AND_DEVICE_OWNERS, 171 permission.MANAGE_USERS, permission.INTERACT_ACROSS_USERS_FULL); 172 public static final String NOT_DEVICE_OWNER_MSG = "does not own the device"; 173 public static final String NOT_PROFILE_OWNER_MSG = "does not own the profile"; 174 public static final String NOT_ORG_OWNED_PROFILE_OWNER_MSG = 175 "not the profile owner on organization-owned device"; 176 public static final String INVALID_CALLING_IDENTITY_MSG = "Calling identity is not authorized"; 177 public static final String ONGOING_CALL_MSG = "ongoing call on the device"; 178 179 // TODO replace all instances of this with explicit {@link #mServiceContext}. 180 @Deprecated 181 private DpmMockContext mContext; 182 183 private DpmMockContext mServiceContext; 184 private DpmMockContext mAdmin1Context; 185 public DevicePolicyManager dpm; 186 public DevicePolicyManager parentDpm; 187 public DevicePolicyManagerServiceTestable dpms; 188 189 private boolean mIsAutomotive; 190 191 /* 192 * The CA cert below is the content of cacert.pem as generated by: 193 * 194 * openssl req -new -x509 -days 3650 -extensions v3_ca -keyout cakey.pem -out cacert.pem 195 */ 196 private static final String TEST_CA = 197 "-----BEGIN CERTIFICATE-----\n" + 198 "MIIDXTCCAkWgAwIBAgIJAK9Tl/F9V8kSMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV\n" + 199 "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n" + 200 "aWRnaXRzIFB0eSBMdGQwHhcNMTUwMzA2MTczMjExWhcNMjUwMzAzMTczMjExWjBF\n" + 201 "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n" + 202 "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB\n" + 203 "CgKCAQEAvItOutsE75WBTgTyNAHt4JXQ3JoseaGqcC3WQij6vhrleWi5KJ0jh1/M\n" + 204 "Rpry7Fajtwwb4t8VZa0NuM2h2YALv52w1xivql88zce/HU1y7XzbXhxis9o6SCI+\n" + 205 "oVQSbPeXRgBPppFzBEh3ZqYTVhAqw451XhwdA4Aqs3wts7ddjwlUzyMdU44osCUg\n" + 206 "kVg7lfPf9sTm5IoHVcfLSCWH5n6Nr9sH3o2ksyTwxuOAvsN11F/a0mmUoPciYPp+\n" + 207 "q7DzQzdi7akRG601DZ4YVOwo6UITGvDyuAAdxl5isovUXqe6Jmz2/myTSpAKxGFs\n" + 208 "jk9oRoG6WXWB1kni490GIPjJ1OceyQIDAQABo1AwTjAdBgNVHQ4EFgQUH1QIlPKL\n" + 209 "p2OQ/AoLOjKvBW4zK3AwHwYDVR0jBBgwFoAUH1QIlPKLp2OQ/AoLOjKvBW4zK3Aw\n" + 210 "DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAcMi4voMMJHeQLjtq8Oky\n" + 211 "Azpyk8moDwgCd4llcGj7izOkIIFqq/lyqKdtykVKUWz2bSHO5cLrtaOCiBWVlaCV\n" + 212 "DYAnnVLM8aqaA6hJDIfaGs4zmwz0dY8hVMFCuCBiLWuPfiYtbEmjHGSmpQTG6Qxn\n" + 213 "ZJlaK5CZyt5pgh5EdNdvQmDEbKGmu0wpCq9qjZImwdyAul1t/B0DrsWApZMgZpeI\n" + 214 "d2od0VBrCICB1K4p+C51D93xyQiva7xQcCne+TAnGNy9+gjQ/MyR8MRpwRLv5ikD\n" + 215 "u0anJCN8pXo6IMglfMAsoton1J6o5/ae5uhC6caQU8bNUsCK570gpNfjkzo6rbP0\n" + 216 "wQ==\n" + 217 "-----END CERTIFICATE-----\n"; 218 219 // Constants for testing setManagedProfileMaximumTimeOff: 220 // Profile maximum time off value 221 private static final long PROFILE_OFF_TIMEOUT = TimeUnit.DAYS.toMillis(5); 222 // Synthetic time at the beginning of test. 223 private static final long PROFILE_OFF_START = 1; 224 // Time when warning notification should be posted, 225 private static final long PROFILE_OFF_WARNING_TIME = 226 PROFILE_OFF_START + PROFILE_OFF_TIMEOUT - TimeUnit.DAYS.toMillis(1); 227 // Time when the apps should be suspended 228 private static final long PROFILE_OFF_DEADLINE = PROFILE_OFF_START + PROFILE_OFF_TIMEOUT; 229 // Notification title and text for setManagedProfileMaximumTimeOff tests: 230 private static final String PROFILE_OFF_SUSPENSION_TITLE = "suspension_title"; 231 private static final String PROFILE_OFF_SUSPENSION_TEXT = "suspension_text"; 232 private static final String PROFILE_OFF_SUSPENSION_SOON_TEXT = "suspension_tomorrow_text"; 233 234 @Before setUp()235 public void setUp() throws Exception { 236 237 mContext = getContext(); 238 mServiceContext = mContext; 239 mServiceContext.binder.callingUid = DpmMockContext.CALLER_UID; 240 when(getServices().packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN))) 241 .thenReturn(true); 242 doReturn(Collections.singletonList(new ResolveInfo())) 243 .when(getServices().packageManager).queryBroadcastReceiversAsUser( 244 any(Intent.class), 245 anyInt(), 246 any(UserHandle.class)); 247 248 // Make createContextAsUser to work. 249 mContext.packageName = "com.android.frameworks.servicestests"; 250 getServices().addPackageContext(UserHandle.of(0), mContext); 251 getServices().addPackageContext(UserHandle.of(CALLER_USER_HANDLE), mContext); 252 253 // By default, pretend all users are running and unlocked. 254 when(getServices().userManager.isUserUnlocked(anyInt())).thenReturn(true); 255 256 initializeDpms(); 257 258 Mockito.reset(getServices().usageStatsManagerInternal); 259 Mockito.reset(getServices().networkPolicyManagerInternal); 260 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID); 261 setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID); 262 setUpPackageManagerForAdmin(admin3, DpmMockContext.CALLER_UID); 263 setUpPackageManagerForAdmin(adminNoPerm, DpmMockContext.CALLER_UID); 264 265 mAdmin1Context = new DpmMockContext(getServices(), mRealTestContext); 266 mAdmin1Context.packageName = admin1.getPackageName(); 267 mAdmin1Context.applicationInfo = new ApplicationInfo(); 268 mAdmin1Context.binder.callingUid = DpmMockContext.CALLER_UID; 269 270 setUpUserManager(); 271 272 when(getServices().lockPatternUtils.hasSecureLockScreen()).thenReturn(true); 273 274 mIsAutomotive = mContext.getPackageManager() 275 .hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE); 276 } 277 getMockTransferMetadataManager()278 private TransferOwnershipMetadataManager getMockTransferMetadataManager() { 279 return dpms.mTransferOwnershipMetadataManager; 280 } 281 282 @After tearDown()283 public void tearDown() throws Exception { 284 flushTasks(dpms); 285 getMockTransferMetadataManager().deleteMetadataFile(); 286 } 287 initializeDpms()288 private void initializeDpms() { 289 // Need clearCallingIdentity() to pass permission checks. 290 final long ident = mContext.binder.clearCallingIdentity(); 291 LocalServices.removeServiceForTest(DevicePolicyManagerLiteInternal.class); 292 LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class); 293 294 dpms = new DevicePolicyManagerServiceTestable(getServices(), mContext); 295 dpms.systemReady(SystemService.PHASE_LOCK_SETTINGS_READY); 296 dpms.systemReady(SystemService.PHASE_BOOT_COMPLETED); 297 298 dpm = new DevicePolicyManagerTestable(mContext, dpms); 299 300 parentDpm = new DevicePolicyManagerTestable(mServiceContext, dpms, 301 /* parentInstance= */true); 302 303 mContext.binder.restoreCallingIdentity(ident); 304 } 305 setUpUserManager()306 private void setUpUserManager() { 307 // Emulate UserManager.set/getApplicationRestriction(). 308 final Map<Pair<String, UserHandle>, Bundle> appRestrictions = new HashMap<>(); 309 310 // UM.setApplicationRestrictions() will save to appRestrictions. 311 doAnswer((Answer<Void>) invocation -> { 312 String pkg = (String) invocation.getArguments()[0]; 313 Bundle bundle = (Bundle) invocation.getArguments()[1]; 314 UserHandle user = (UserHandle) invocation.getArguments()[2]; 315 316 appRestrictions.put(Pair.create(pkg, user), bundle); 317 318 return null; 319 }).when(getServices().userManager).setApplicationRestrictions( 320 anyString(), nullable(Bundle.class), any(UserHandle.class)); 321 322 // UM.getApplicationRestrictions() will read from appRestrictions. 323 doAnswer((Answer<Bundle>) invocation -> { 324 String pkg = (String) invocation.getArguments()[0]; 325 UserHandle user = (UserHandle) invocation.getArguments()[1]; 326 327 return appRestrictions.get(Pair.create(pkg, user)); 328 }).when(getServices().userManager).getApplicationRestrictions( 329 anyString(), any(UserHandle.class)); 330 331 // Emulate UserManager.setUserRestriction/getUserRestrictions 332 final Map<UserHandle, Bundle> userRestrictions = new HashMap<>(); 333 334 doAnswer((Answer<Void>) invocation -> { 335 String key = (String) invocation.getArguments()[0]; 336 boolean value = (Boolean) invocation.getArguments()[1]; 337 UserHandle user = (UserHandle) invocation.getArguments()[2]; 338 Bundle userBundle = userRestrictions.getOrDefault(user, new Bundle()); 339 userBundle.putBoolean(key, value); 340 341 userRestrictions.put(user, userBundle); 342 return null; 343 }).when(getServices().userManager).setUserRestriction( 344 anyString(), anyBoolean(), any(UserHandle.class)); 345 346 doAnswer((Answer<Boolean>) invocation -> { 347 String key = (String) invocation.getArguments()[0]; 348 UserHandle user = (UserHandle) invocation.getArguments()[1]; 349 Bundle userBundle = userRestrictions.getOrDefault(user, new Bundle()); 350 return userBundle.getBoolean(key); 351 }).when(getServices().userManager).hasUserRestriction( 352 anyString(), any(UserHandle.class)); 353 354 // Add the first secondary user. 355 getServices().addUser(CALLER_USER_HANDLE, 0, UserManager.USER_TYPE_FULL_SECONDARY); 356 } 357 setAsProfileOwner(ComponentName admin)358 private void setAsProfileOwner(ComponentName admin) { 359 final long ident = mServiceContext.binder.clearCallingIdentity(); 360 361 mServiceContext.binder.callingUid = 362 UserHandle.getUid(CALLER_USER_HANDLE, DpmMockContext.SYSTEM_UID); 363 runAsCaller(mServiceContext, dpms, dpm -> { 364 // PO needs to be a DA. 365 dpm.setActiveAdmin(admin, /*replace=*/ false); 366 // Fire! 367 assertThat(dpm.setProfileOwner(admin, "owner-name", CALLER_USER_HANDLE)).isTrue(); 368 // Check 369 assertThat(dpm.getProfileOwnerAsUser(CALLER_USER_HANDLE)).isEqualTo(admin); 370 }); 371 372 mServiceContext.binder.restoreCallingIdentity(ident); 373 } 374 375 @Test testHasNoFeature()376 public void testHasNoFeature() throws Exception { 377 when(getServices().packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN))) 378 .thenReturn(false); 379 380 LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class); 381 LocalServices.removeServiceForTest(DevicePolicyManagerLiteInternal.class); 382 new DevicePolicyManagerServiceTestable(getServices(), mContext); 383 384 // If the device has no DPMS feature, it shouldn't register the local service. 385 assertThat(LocalServices.getService(DevicePolicyManagerInternal.class)).isNull(); 386 387 // But should still register the lite one 388 assertThat(LocalServices.getService(DevicePolicyManagerLiteInternal.class)).isNotNull(); 389 } 390 391 @Test testLoadAdminData()392 public void testLoadAdminData() throws Exception { 393 // Device owner in SYSTEM_USER 394 setDeviceOwner(); 395 // Profile owner in CALLER_USER_HANDLE 396 setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID); 397 setAsProfileOwner(admin2); 398 // Active admin in CALLER_USER_HANDLE 399 final int ANOTHER_UID = UserHandle.getUid(CALLER_USER_HANDLE, 1306); 400 setUpPackageManagerForFakeAdmin(adminAnotherPackage, ANOTHER_UID, admin2); 401 dpm.setActiveAdmin(adminAnotherPackage, /* replace =*/ false, CALLER_USER_HANDLE); 402 assertThat(dpm.isAdminActiveAsUser(adminAnotherPackage, CALLER_USER_HANDLE)).isTrue(); 403 404 initializeDpms(); 405 406 // Verify 407 verify(getServices().usageStatsManagerInternal).setActiveAdminApps( 408 MockUtils.checkApps(admin1.getPackageName()), 409 eq(UserHandle.USER_SYSTEM)); 410 verify(getServices().usageStatsManagerInternal).setActiveAdminApps( 411 MockUtils.checkApps(admin2.getPackageName(), 412 adminAnotherPackage.getPackageName()), 413 eq(CALLER_USER_HANDLE)); 414 verify(getServices().usageStatsManagerInternal).onAdminDataAvailable(); 415 verify(getServices().networkPolicyManagerInternal).onAdminDataAvailable(); 416 } 417 418 @Test testLoadAdminData_noAdmins()419 public void testLoadAdminData_noAdmins() throws Exception { 420 final int ANOTHER_USER_ID = 15; 421 getServices().addUser(ANOTHER_USER_ID, 0, ""); 422 423 initializeDpms(); 424 425 // Verify 426 verify(getServices().usageStatsManagerInternal).setActiveAdminApps( 427 null, CALLER_USER_HANDLE); 428 verify(getServices().usageStatsManagerInternal).setActiveAdminApps( 429 null, ANOTHER_USER_ID); 430 verify(getServices().usageStatsManagerInternal).onAdminDataAvailable(); 431 verify(getServices().networkPolicyManagerInternal).onAdminDataAvailable(); 432 } 433 434 /** 435 * Caller doesn't have proper permissions. 436 */ 437 @Test testSetActiveAdmin_SecurityException()438 public void testSetActiveAdmin_SecurityException() { 439 // 1. Failure cases. 440 441 // Caller doesn't have MANAGE_DEVICE_ADMINS. 442 assertExpectException(SecurityException.class, /* messageRegex= */ null, 443 () -> dpm.setActiveAdmin(admin1, false)); 444 445 // Caller has MANAGE_DEVICE_ADMINS, but for different user. 446 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 447 448 assertExpectException(SecurityException.class, /* messageRegex= */ null, 449 () -> dpm.setActiveAdmin(admin1, false, CALLER_USER_HANDLE + 1)); 450 } 451 452 /** 453 * Test for: 454 * {@link DevicePolicyManager#setActiveAdmin} 455 * with replace=false and replace=true 456 * {@link DevicePolicyManager#isAdminActive} 457 * {@link DevicePolicyManager#isAdminActiveAsUser} 458 * {@link DevicePolicyManager#getActiveAdmins} 459 * {@link DevicePolicyManager#getActiveAdminsAsUser} 460 */ 461 @Test testSetActiveAdmin()462 public void testSetActiveAdmin() throws Exception { 463 // 1. Make sure the caller has proper permissions. 464 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 465 466 // 2. Call the API. 467 dpm.setActiveAdmin(admin1, /* replace =*/ false); 468 469 // 3. Verify internal calls. 470 471 // Check if the boradcast is sent. 472 verify(mContext.spiedContext).sendBroadcastAsUser( 473 MockUtils.checkIntentAction( 474 DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED), 475 MockUtils.checkUserHandle(CALLER_USER_HANDLE)); 476 verify(mContext.spiedContext).sendBroadcastAsUser( 477 MockUtils.checkIntentAction( 478 DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED), 479 MockUtils.checkUserHandle(CALLER_USER_HANDLE), 480 eq(null), 481 any(Bundle.class)); 482 483 verify(getServices().ipackageManager, times(1)).setApplicationEnabledSetting( 484 eq(admin1.getPackageName()), 485 eq(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT), 486 eq(PackageManager.DONT_KILL_APP), 487 eq(CALLER_USER_HANDLE), 488 anyString()); 489 490 verify(getServices().usageStatsManagerInternal).onActiveAdminAdded( 491 admin1.getPackageName(), CALLER_USER_HANDLE); 492 493 // TODO Verify other calls too. 494 495 // Make sure it's active admin1. 496 assertThat(dpm.isAdminActive(admin1)).isTrue(); 497 assertThat(dpm.isAdminActive(admin2)).isFalse(); 498 assertThat(dpm.isAdminActive(admin3)).isFalse(); 499 500 // But not admin1 for a different user. 501 502 // For this to work, caller needs android.permission.INTERACT_ACROSS_USERS_FULL. 503 // (Because we're checking a different user's status from CALLER_USER_HANDLE.) 504 mContext.callerPermissions.add("android.permission.INTERACT_ACROSS_USERS_FULL"); 505 506 assertThat(dpm.isAdminActiveAsUser(admin1, CALLER_USER_HANDLE + 1)).isFalse(); 507 assertThat(dpm.isAdminActiveAsUser(admin2, CALLER_USER_HANDLE + 1)).isFalse(); 508 509 mContext.callerPermissions.remove("android.permission.INTERACT_ACROSS_USERS_FULL"); 510 511 // Next, add one more admin. 512 // Before doing so, update the application info, now it's enabled. 513 setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID, 514 PackageManager.COMPONENT_ENABLED_STATE_DEFAULT); 515 516 dpm.setActiveAdmin(admin2, /* replace =*/ false); 517 518 // Now we have two admins. 519 assertThat(dpm.isAdminActive(admin1)).isTrue(); 520 assertThat(dpm.isAdminActive(admin2)).isTrue(); 521 assertThat(dpm.isAdminActive(admin3)).isFalse(); 522 523 // Admin2 was already enabled, so setApplicationEnabledSetting() shouldn't have called 524 // again. (times(1) because it was previously called for admin1) 525 verify(getServices().ipackageManager, times(1)).setApplicationEnabledSetting( 526 eq(admin1.getPackageName()), 527 eq(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT), 528 eq(PackageManager.DONT_KILL_APP), 529 eq(CALLER_USER_HANDLE), 530 anyString()); 531 532 // times(2) because it was previously called for admin1 which is in the same package 533 // as admin2. 534 verify(getServices().usageStatsManagerInternal, times(2)).onActiveAdminAdded( 535 admin2.getPackageName(), CALLER_USER_HANDLE); 536 537 // 4. Add the same admin1 again without replace, which should throw. 538 assertExpectException(IllegalArgumentException.class, /* messageRegex= */ null, 539 () -> dpm.setActiveAdmin(admin1, /* replace =*/ false)); 540 541 // 5. Add the same admin1 again with replace, which should succeed. 542 dpm.setActiveAdmin(admin1, /* replace =*/ true); 543 544 // TODO make sure it's replaced. 545 546 // 6. Test getActiveAdmins() 547 List<ComponentName> admins = dpm.getActiveAdmins(); 548 assertThat(admins.size()).isEqualTo(2); 549 assertThat(admins.get(0)).isEqualTo(admin1); 550 assertThat(admins.get(1)).isEqualTo(admin2); 551 552 // There shouldn't be any callback to UsageStatsManagerInternal when the admin is being 553 // replaced 554 verifyNoMoreInteractions(getServices().usageStatsManagerInternal); 555 556 // Another user has no admins. 557 mContext.callerPermissions.add("android.permission.INTERACT_ACROSS_USERS_FULL"); 558 559 assertThat(DpmTestUtils.getListSizeAllowingNull( 560 dpm.getActiveAdminsAsUser(CALLER_USER_HANDLE + 1))).isEqualTo(0); 561 562 mContext.callerPermissions.remove("android.permission.INTERACT_ACROSS_USERS_FULL"); 563 } 564 565 @Test testSetActiveAdmin_multiUsers()566 public void testSetActiveAdmin_multiUsers() throws Exception { 567 568 final int ANOTHER_USER_ID = 100; 569 final int ANOTHER_ADMIN_UID = UserHandle.getUid(ANOTHER_USER_ID, 20456); 570 571 getServices().addUser(ANOTHER_USER_ID, 0, ""); // Add one more user. 572 573 // Set up pacakge manager for the other user. 574 setUpPackageManagerForAdmin(admin2, ANOTHER_ADMIN_UID); 575 576 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 577 578 dpm.setActiveAdmin(admin1, /* replace =*/ false); 579 580 mMockContext.binder.callingUid = ANOTHER_ADMIN_UID; 581 dpm.setActiveAdmin(admin2, /* replace =*/ false); 582 583 584 mMockContext.binder.callingUid = DpmMockContext.CALLER_UID; 585 assertThat(dpm.isAdminActive(admin1)).isTrue(); 586 assertThat(dpm.isAdminActive(admin2)).isFalse(); 587 588 mMockContext.binder.callingUid = ANOTHER_ADMIN_UID; 589 assertThat(dpm.isAdminActive(admin1)).isFalse(); 590 assertThat(dpm.isAdminActive(admin2)).isTrue(); 591 } 592 593 /** 594 * Test for: 595 * {@link DevicePolicyManager#setActiveAdmin} 596 * with replace=false 597 */ 598 @Test testSetActiveAdmin_twiceWithoutReplace()599 public void testSetActiveAdmin_twiceWithoutReplace() throws Exception { 600 // 1. Make sure the caller has proper permissions. 601 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 602 603 dpm.setActiveAdmin(admin1, /* replace =*/ false); 604 assertThat(dpm.isAdminActive(admin1)).isTrue(); 605 606 // Add the same admin1 again without replace, which should throw. 607 assertExpectException(IllegalArgumentException.class, /* messageRegex= */ null, 608 () -> dpm.setActiveAdmin(admin1, /* replace =*/ false)); 609 } 610 611 /** 612 * Test for: 613 * {@link DevicePolicyManager#setActiveAdmin} when the admin isn't protected with 614 * BIND_DEVICE_ADMIN. 615 */ 616 @Test testSetActiveAdmin_permissionCheck()617 public void testSetActiveAdmin_permissionCheck() throws Exception { 618 // 1. Make sure the caller has proper permissions. 619 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 620 621 assertExpectException(IllegalArgumentException.class, 622 /* messageRegex= */ permission.BIND_DEVICE_ADMIN, 623 () -> dpm.setActiveAdmin(adminNoPerm, /* replace =*/ false)); 624 assertThat(dpm.isAdminActive(adminNoPerm)).isFalse(); 625 626 // Change the target API level to MNC. Now it can be set as DA. 627 setUpPackageManagerForAdmin(adminNoPerm, DpmMockContext.CALLER_UID, null, 628 VERSION_CODES.M); 629 dpm.setActiveAdmin(adminNoPerm, /* replace =*/ false); 630 assertThat(dpm.isAdminActive(adminNoPerm)).isTrue(); 631 632 // TODO Test the "load from the file" case where DA will still be loaded even without 633 // BIND_DEVICE_ADMIN and target API is N. 634 } 635 636 /** 637 * Test for: 638 * {@link DevicePolicyManager#removeActiveAdmin} 639 */ 640 @Test testRemoveActiveAdmin_SecurityException()641 public void testRemoveActiveAdmin_SecurityException() { 642 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 643 644 // Add admin. 645 646 dpm.setActiveAdmin(admin1, /* replace =*/ false); 647 648 assertThat(dpm.isAdminActive(admin1)).isTrue(); 649 650 assertThat(dpm.isRemovingAdmin(admin1, CALLER_USER_HANDLE)).isFalse(); 651 652 // Directly call the DPMS method with a different userid, which should fail. 653 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 654 () -> dpms.removeActiveAdmin(admin1, CALLER_USER_HANDLE + 1)); 655 656 // Try to remove active admin with a different caller userid should fail too, without 657 // having MANAGE_DEVICE_ADMINS. 658 mContext.callerPermissions.clear(); 659 660 // Change the caller, and call into DPMS directly with a different user-id. 661 662 mContext.binder.callingUid = 1234567; 663 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 664 () -> dpms.removeActiveAdmin(admin1, CALLER_USER_HANDLE)); 665 } 666 667 /** 668 * {@link DevicePolicyManager#removeActiveAdmin} should fail with the user is not unlocked 669 * (because we can't send the remove broadcast). 670 */ 671 @Test testRemoveActiveAdmin_userNotRunningOrLocked()672 public void testRemoveActiveAdmin_userNotRunningOrLocked() { 673 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 674 675 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 676 677 // Add admin. 678 679 dpm.setActiveAdmin(admin1, /* replace =*/ false); 680 681 assertThat(dpm.isAdminActive(admin1)).isTrue(); 682 683 assertThat(dpm.isRemovingAdmin(admin1, CALLER_USER_HANDLE)).isFalse(); 684 685 // 1. User not unlocked. 686 setUserUnlocked(CALLER_USER_HANDLE, false); 687 assertExpectException(IllegalStateException.class, 688 /* messageRegex= */ "User must be running and unlocked", 689 () -> dpm.removeActiveAdmin(admin1)); 690 691 assertThat(dpm.isRemovingAdmin(admin1, CALLER_USER_HANDLE)).isFalse(); 692 verify(getServices().usageStatsManagerInternal, times(0)).setActiveAdminApps( 693 null, CALLER_USER_HANDLE); 694 695 // 2. User unlocked. 696 setUserUnlocked(CALLER_USER_HANDLE, true); 697 698 dpm.removeActiveAdmin(admin1); 699 assertThat(dpm.isAdminActiveAsUser(admin1, CALLER_USER_HANDLE)).isFalse(); 700 verify(getServices().usageStatsManagerInternal).setActiveAdminApps( 701 null, CALLER_USER_HANDLE); 702 } 703 704 /** 705 * Test for: 706 * {@link DevicePolicyManager#removeActiveAdmin} 707 */ 708 @Test testRemoveActiveAdmin_fromDifferentUserWithINTERACT_ACROSS_USERS_FULL()709 public void testRemoveActiveAdmin_fromDifferentUserWithINTERACT_ACROSS_USERS_FULL() { 710 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 711 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS); 712 713 // Add admin1. 714 715 dpm.setActiveAdmin(admin1, /* replace =*/ false); 716 717 assertThat(dpm.isAdminActive(admin1)).isTrue(); 718 assertThat(dpm.isRemovingAdmin(admin1, CALLER_USER_HANDLE)).isFalse(); 719 720 // Different user, but should work, because caller has proper permissions. 721 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); 722 723 // Change the caller, and call into DPMS directly with a different user-id. 724 mContext.binder.callingUid = 1234567; 725 726 dpms.removeActiveAdmin(admin1, CALLER_USER_HANDLE); 727 assertThat(dpm.isAdminActiveAsUser(admin1, CALLER_USER_HANDLE)).isFalse(); 728 verify(getServices().usageStatsManagerInternal).setActiveAdminApps( 729 null, CALLER_USER_HANDLE); 730 731 // TODO DO Still can't be removed in this case. 732 } 733 734 /** 735 * Test for: 736 * {@link DevicePolicyManager#removeActiveAdmin} 737 */ 738 @Test testRemoveActiveAdmin_sameUserNoMANAGE_DEVICE_ADMINS()739 public void testRemoveActiveAdmin_sameUserNoMANAGE_DEVICE_ADMINS() { 740 // Need MANAGE_DEVICE_ADMINS for setActiveAdmin. We'll remove it later. 741 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 742 743 // Add admin1. 744 745 dpm.setActiveAdmin(admin1, /* replace =*/ false); 746 747 assertThat(dpm.isAdminActive(admin1)).isTrue(); 748 assertThat(dpm.isRemovingAdmin(admin1, CALLER_USER_HANDLE)).isFalse(); 749 750 // Broadcast from saveSettingsLocked(). 751 verify(mContext.spiedContext, times(1)).sendBroadcastAsUser( 752 MockUtils.checkIntentAction( 753 DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED), 754 MockUtils.checkUserHandle(CALLER_USER_HANDLE)); 755 756 // Remove. No permissions, but same user, so it'll work. 757 mContext.callerPermissions.clear(); 758 dpm.removeActiveAdmin(admin1); 759 760 verify(mContext.spiedContext).sendOrderedBroadcastAsUser( 761 MockUtils.checkIntentAction( 762 DeviceAdminReceiver.ACTION_DEVICE_ADMIN_DISABLED), 763 MockUtils.checkUserHandle(CALLER_USER_HANDLE), 764 isNull(String.class), 765 eq(AppOpsManager.OP_NONE), 766 any(Bundle.class), 767 any(BroadcastReceiver.class), 768 eq(dpms.mHandler), 769 eq(Activity.RESULT_OK), 770 isNull(String.class), 771 isNull(Bundle.class)); 772 773 assertThat(dpm.isAdminActiveAsUser(admin1, CALLER_USER_HANDLE)).isFalse(); 774 verify(getServices().usageStatsManagerInternal).setActiveAdminApps( 775 null, CALLER_USER_HANDLE); 776 777 // Again broadcast from saveSettingsLocked(). 778 verify(mContext.spiedContext, times(2)).sendBroadcastAsUser( 779 MockUtils.checkIntentAction( 780 DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED), 781 MockUtils.checkUserHandle(CALLER_USER_HANDLE)); 782 783 // TODO Check other internal calls. 784 } 785 786 @Test testRemoveActiveAdmin_multipleAdminsInUser()787 public void testRemoveActiveAdmin_multipleAdminsInUser() { 788 // Need MANAGE_DEVICE_ADMINS for setActiveAdmin. We'll remove it later. 789 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 790 791 // Add admin1. 792 dpm.setActiveAdmin(admin1, /* replace =*/ false); 793 794 assertThat(dpm.isAdminActive(admin1)).isTrue(); 795 assertThat(dpm.isRemovingAdmin(admin1, CALLER_USER_HANDLE)).isFalse(); 796 797 // Add admin2. 798 dpm.setActiveAdmin(admin2, /* replace =*/ false); 799 800 assertThat(dpm.isAdminActive(admin2)).isTrue(); 801 assertThat(dpm.isRemovingAdmin(admin2, CALLER_USER_HANDLE)).isFalse(); 802 803 // Broadcast from saveSettingsLocked(). 804 verify(mContext.spiedContext, times(2)).sendBroadcastAsUser( 805 MockUtils.checkIntentAction( 806 DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED), 807 MockUtils.checkUserHandle(CALLER_USER_HANDLE)); 808 809 // Remove. No permissions, but same user, so it'll work. 810 mContext.callerPermissions.clear(); 811 dpm.removeActiveAdmin(admin1); 812 813 verify(mContext.spiedContext).sendOrderedBroadcastAsUser( 814 MockUtils.checkIntentAction( 815 DeviceAdminReceiver.ACTION_DEVICE_ADMIN_DISABLED), 816 MockUtils.checkUserHandle(CALLER_USER_HANDLE), 817 isNull(String.class), 818 eq(AppOpsManager.OP_NONE), 819 any(Bundle.class), 820 any(BroadcastReceiver.class), 821 eq(dpms.mHandler), 822 eq(Activity.RESULT_OK), 823 isNull(String.class), 824 isNull(Bundle.class)); 825 826 assertThat(dpm.isAdminActiveAsUser(admin1, CALLER_USER_HANDLE)).isFalse(); 827 verify(getServices().usageStatsManagerInternal).setActiveAdminApps( 828 MockUtils.checkApps(admin2.getPackageName()), 829 eq(CALLER_USER_HANDLE)); 830 831 // Again broadcast from saveSettingsLocked(). 832 verify(mContext.spiedContext, times(3)).sendBroadcastAsUser( 833 MockUtils.checkIntentAction( 834 DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED), 835 MockUtils.checkUserHandle(CALLER_USER_HANDLE)); 836 } 837 838 /** 839 * Test for: 840 * {@link DevicePolicyManager#forceRemoveActiveAdmin(ComponentName, int)} 841 */ 842 @Test testForceRemoveActiveAdmin_nonShellCaller()843 public void testForceRemoveActiveAdmin_nonShellCaller() throws Exception { 844 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 845 846 // Add admin. 847 setupPackageInPackageManager(admin1.getPackageName(), 848 /* userId= */ CALLER_USER_HANDLE, 849 /* appId= */ 10138, 850 /* flags= */ ApplicationInfo.FLAG_TEST_ONLY); 851 dpm.setActiveAdmin(admin1, /* replace =*/ false); 852 assertThat(dpm.isAdminActive(admin1)).isTrue(); 853 854 // Calling from a non-shell uid should fail with a SecurityException 855 mContext.binder.callingUid = 123456; 856 assertExpectException(SecurityException.class, 857 /* messageRegex = */ null, 858 () -> dpms.forceRemoveActiveAdmin(admin1, CALLER_USER_HANDLE)); 859 } 860 861 /** 862 * Test for: 863 * {@link DevicePolicyManager#forceRemoveActiveAdmin(ComponentName, int)} 864 */ 865 @Test testForceRemoveActiveAdmin_nonShellCallerWithPermission()866 public void testForceRemoveActiveAdmin_nonShellCallerWithPermission() throws Exception { 867 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 868 869 // Add admin. 870 setupPackageInPackageManager(admin1.getPackageName(), 871 /* userId= */ CALLER_USER_HANDLE, 872 /* appId= */ 10138, 873 /* flags= */ ApplicationInfo.FLAG_TEST_ONLY); 874 dpm.setActiveAdmin(admin1, /* replace =*/ false); 875 assertThat(dpm.isAdminActive(admin1)).isTrue(); 876 877 mContext.binder.callingUid = 123456; 878 mContext.callerPermissions.add( 879 android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 880 dpms.forceRemoveActiveAdmin(admin1, CALLER_USER_HANDLE); 881 882 mContext.callerPermissions.add(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 883 // Verify 884 assertThat(dpm.isAdminActiveAsUser(admin1, CALLER_USER_HANDLE)).isFalse(); 885 verify(getServices().usageStatsManagerInternal).setActiveAdminApps( 886 null, CALLER_USER_HANDLE); 887 } 888 889 /** 890 * Test for: 891 * {@link DevicePolicyManager#forceRemoveActiveAdmin(ComponentName, int)} 892 */ 893 @Test testForceRemoveActiveAdmin_ShellCaller()894 public void testForceRemoveActiveAdmin_ShellCaller() throws Exception { 895 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 896 897 // Add admin. 898 setupPackageInPackageManager(admin1.getPackageName(), 899 /* userId= */ CALLER_USER_HANDLE, 900 /* appId= */ 10138, 901 /* flags= */ ApplicationInfo.FLAG_TEST_ONLY); 902 dpm.setActiveAdmin(admin1, /* replace =*/ false); 903 assertThat(dpm.isAdminActive(admin1)).isTrue(); 904 905 mContext.binder.callingUid = Process.SHELL_UID; 906 dpms.forceRemoveActiveAdmin(admin1, CALLER_USER_HANDLE); 907 908 mContext.callerPermissions.add(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 909 // Verify 910 assertThat(dpm.isAdminActiveAsUser(admin1, CALLER_USER_HANDLE)).isFalse(); 911 verify(getServices().usageStatsManagerInternal).setActiveAdminApps( 912 null, CALLER_USER_HANDLE); 913 } 914 915 /** 916 * Test for: {@link DevicePolicyManager#setPasswordHistoryLength(ComponentName, int)} 917 * 918 * Validates that when the password history length is set, it is persisted after rebooting 919 */ 920 @Test testSaveAndLoadPasswordHistoryLength_persistedAfterReboot()921 public void testSaveAndLoadPasswordHistoryLength_persistedAfterReboot() throws Exception { 922 int passwordHistoryLength = 2; 923 924 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 925 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 926 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 927 928 // Install admin1 on system user. 929 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 930 931 // Set admin1 to active admin and device owner 932 dpm.setActiveAdmin(admin1, false); 933 dpm.setDeviceOwner(admin1, null, UserHandle.USER_SYSTEM); 934 935 // Save password history length 936 dpm.setPasswordHistoryLength(admin1, passwordHistoryLength); 937 938 assertThat(passwordHistoryLength).isEqualTo(dpm.getPasswordHistoryLength(admin1)); 939 940 initializeDpms(); 941 reset(mContext.spiedContext); 942 943 // Password history length should persist after rebooted 944 assertThat(passwordHistoryLength).isEqualTo(dpm.getPasswordHistoryLength(admin1)); 945 } 946 947 /** 948 * Test for: {@link DevicePolicyManager#reportPasswordChanged} 949 * 950 * Validates that when the password for a user changes, the notification broadcast intent 951 * {@link DeviceAdminReceiver#ACTION_PASSWORD_CHANGED} is sent to managed profile owners, in 952 * addition to ones in the original user. 953 */ 954 @Test testSetActivePasswordState_sendToProfiles()955 public void testSetActivePasswordState_sendToProfiles() throws Exception { 956 mContext.callerPermissions.add(permission.BIND_DEVICE_ADMIN); 957 958 final int MANAGED_PROFILE_USER_ID = 78; 959 final int MANAGED_PROFILE_ADMIN_UID = 960 UserHandle.getUid(MANAGED_PROFILE_USER_ID, DpmMockContext.SYSTEM_UID); 961 962 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 963 mContext.packageName = admin1.getPackageName(); 964 965 // Add a managed profile belonging to the system user. 966 addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1); 967 968 // Change the parent user's password. 969 dpm.reportPasswordChanged(UserHandle.USER_SYSTEM); 970 971 // The managed profile owner should receive this broadcast. 972 final Intent intent = new Intent(DeviceAdminReceiver.ACTION_PASSWORD_CHANGED); 973 intent.setComponent(admin1); 974 intent.putExtra(Intent.EXTRA_USER, UserHandle.of(UserHandle.USER_SYSTEM)); 975 976 verify(mContext.spiedContext, times(1)).sendBroadcastAsUser( 977 MockUtils.checkIntent(intent), 978 MockUtils.checkUserHandle(MANAGED_PROFILE_USER_ID), 979 eq(null), 980 any(Bundle.class)); 981 } 982 983 /** 984 * Test for: @{link DevicePolicyManager#reportPasswordChanged} 985 * 986 * Validates that when the password for a managed profile changes, the notification broadcast 987 * intent {@link DeviceAdminReceiver#ACTION_PASSWORD_CHANGED} is only sent to the profile, not 988 * its parent. 989 */ 990 @Test testSetActivePasswordState_notSentToParent()991 public void testSetActivePasswordState_notSentToParent() throws Exception { 992 mContext.callerPermissions.add(permission.BIND_DEVICE_ADMIN); 993 994 final int MANAGED_PROFILE_USER_ID = 78; 995 final int MANAGED_PROFILE_ADMIN_UID = 996 UserHandle.getUid(MANAGED_PROFILE_USER_ID, DpmMockContext.SYSTEM_UID); 997 998 // Configure system as having separate profile challenge. 999 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 1000 mContext.packageName = admin1.getPackageName(); 1001 doReturn(true).when(getServices().lockPatternUtils) 1002 .isSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID); 1003 1004 // Add a managed profile belonging to the system user. 1005 addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1); 1006 1007 // Change the profile's password. 1008 dpm.reportPasswordChanged(MANAGED_PROFILE_USER_ID); 1009 1010 // Both the device owner and the managed profile owner should receive this broadcast. 1011 final Intent intent = new Intent(DeviceAdminReceiver.ACTION_PASSWORD_CHANGED); 1012 intent.setComponent(admin1); 1013 intent.putExtra(Intent.EXTRA_USER, UserHandle.of(MANAGED_PROFILE_USER_ID)); 1014 1015 verify(mContext.spiedContext, never()).sendBroadcastAsUser( 1016 MockUtils.checkIntent(intent), 1017 MockUtils.checkUserHandle(UserHandle.USER_SYSTEM), 1018 eq(null), 1019 any(Bundle.class)); 1020 verify(mContext.spiedContext, times(1)).sendBroadcastAsUser( 1021 MockUtils.checkIntent(intent), 1022 MockUtils.checkUserHandle(MANAGED_PROFILE_USER_ID), 1023 eq(null), 1024 any(Bundle.class)); 1025 } 1026 1027 /** 1028 * Test for: {@link DevicePolicyManager#setDeviceOwner} DO on system user installs successfully. 1029 */ 1030 @Test testSetDeviceOwner()1031 public void testSetDeviceOwner() throws Exception { 1032 setDeviceOwner(); 1033 1034 // Try to set a profile owner on the same user, which should fail. 1035 setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_SYSTEM_USER_UID); 1036 dpm.setActiveAdmin(admin2, /* refreshing= */ true, UserHandle.USER_SYSTEM); 1037 assertExpectException(IllegalStateException.class, 1038 /* messageRegex= */ "already has a device owner", 1039 () -> dpm.setProfileOwner(admin2, "owner-name", UserHandle.USER_SYSTEM)); 1040 1041 // DO admin can't be deactivated. 1042 dpm.removeActiveAdmin(admin1); 1043 assertThat(dpm.isAdminActive(admin1)).isTrue(); 1044 1045 // TODO Test getDeviceOwnerName() too. To do so, we need to change 1046 // DPMS.getApplicationLabel() because Context.createPackageContextAsUser() is not mockable. 1047 } 1048 1049 /** 1050 * TODO(b/174859111): move to automotive-only section 1051 * Test for {@link DevicePolicyManager#setDeviceOwner} in headless system user mode. 1052 */ 1053 @Test testSetDeviceOwner_headlessSystemUserMode()1054 public void testSetDeviceOwner_headlessSystemUserMode() throws Exception { 1055 when(getServices().userManagerForMock.isHeadlessSystemUserMode()).thenReturn(true); 1056 setDeviceOwner_headlessSystemUser(); 1057 1058 // Try to set a profile owner on the same user, which should fail. 1059 setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID); 1060 dpm.setActiveAdmin(admin2, /* refreshing= */ true, CALLER_USER_HANDLE); 1061 assertExpectException(IllegalStateException.class, 1062 /* messageRegex= */ "profile owner is already set", 1063 () -> dpm.setProfileOwner(admin2, "owner-name", CALLER_USER_HANDLE)); 1064 1065 // DO admin can't be deactivated. 1066 dpm.removeActiveAdmin(admin1); 1067 assertThat(dpm.isAdminActive(admin1)).isTrue(); 1068 } 1069 setDeviceOwner()1070 private void setDeviceOwner() throws Exception { 1071 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 1072 mContext.callerPermissions.add(permission.MANAGE_USERS); 1073 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 1074 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); 1075 1076 // In this test, change the caller user to "system". 1077 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 1078 1079 // Make sure admin1 is installed on system user. 1080 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 1081 1082 // Check various get APIs. 1083 checkGetDeviceOwnerInfoApi(dpm, /* hasDeviceOwner =*/ false); 1084 1085 // DO needs to be an DA. 1086 dpm.setActiveAdmin(admin1, /* replace =*/ false); 1087 1088 // Fire! 1089 assertThat(dpm.setDeviceOwner(admin1, "owner-name")).isTrue(); 1090 1091 // getDeviceOwnerComponent should return the admin1 component. 1092 assertThat(dpm.getDeviceOwnerComponentOnCallingUser()).isEqualTo(admin1); 1093 assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isEqualTo(admin1); 1094 1095 // Check various get APIs. 1096 checkGetDeviceOwnerInfoApi(dpm, /* hasDeviceOwner =*/ true); 1097 1098 // getDeviceOwnerComponent should *NOT* return the admin1 component for other users. 1099 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 1100 assertThat(dpm.getDeviceOwnerComponentOnCallingUser()).isEqualTo(null); 1101 assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isEqualTo(admin1); 1102 1103 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 1104 1105 // Verify internal calls. 1106 verify(getServices().iactivityManager, times(1)).updateDeviceOwner( 1107 eq(admin1.getPackageName())); 1108 1109 verify(getServices().userManager, times(1)).setUserRestriction( 1110 eq(UserManager.DISALLOW_ADD_MANAGED_PROFILE), 1111 eq(true), eq(UserHandle.SYSTEM)); 1112 1113 verify(mContext.spiedContext, times(1)).sendBroadcastAsUser( 1114 MockUtils.checkIntentAction(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED), 1115 MockUtils.checkUserHandle(UserHandle.USER_SYSTEM)); 1116 1117 assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isEqualTo(admin1); 1118 } 1119 1120 // TODO(b/174859111): move to automotive-only section setDeviceOwner_headlessSystemUser()1121 private void setDeviceOwner_headlessSystemUser() throws Exception { 1122 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 1123 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 1124 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); 1125 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS); 1126 mContext.callerPermissions.add(permission.MANAGE_USERS); 1127 1128 when(getServices().iactivityManager.getCurrentUser()).thenReturn( 1129 new UserInfo(DpmMockContext.CALLER_USER_HANDLE, "caller", /* flags=*/ 0)); 1130 // Check various get APIs. 1131 checkGetDeviceOwnerInfoApi(dpm, /* hasDeviceOwner =*/ false); 1132 1133 final long ident = mServiceContext.binder.clearCallingIdentity(); 1134 1135 mServiceContext.binder.callingUid = DpmMockContext.CALLER_UID; 1136 1137 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 1138 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID); 1139 1140 // Set device owner 1141 runAsCaller(mServiceContext, dpms, dpm -> { 1142 // DO needs to be a DA 1143 dpm.setActiveAdmin(admin1, /* replace =*/ false, UserHandle.USER_SYSTEM); 1144 // DO should be set on headless system user 1145 assertThat(dpm.setDeviceOwner(admin1, "owner-name", UserHandle.USER_SYSTEM)).isTrue(); 1146 // PO should be set on calling user. 1147 assertThat(dpm.getProfileOwnerAsUser(CALLER_USER_HANDLE)).isEqualTo(admin1); 1148 }); 1149 1150 mServiceContext.binder.restoreCallingIdentity(ident); 1151 1152 // Check various get APIs. 1153 checkGetDeviceOwnerInfoApi(dpm, /* hasDeviceOwner =*/ true); 1154 1155 // Add MANAGE_USERS or test purpose. 1156 mContext.callerPermissions.add(permission.MANAGE_USERS); 1157 // getDeviceOwnerComponent should *NOT* return the admin1 component for calling user. 1158 assertThat(dpm.getDeviceOwnerComponentOnCallingUser()).isNull(); 1159 // Device owner should be set on system user. 1160 assertThat(dpm.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_SYSTEM); 1161 1162 // Set calling user to be system user. 1163 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 1164 1165 // Device owner component should be admin1 1166 assertThat(dpm.getDeviceOwnerComponentOnCallingUser()).isEqualTo(admin1); 1167 assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isEqualTo(admin1); 1168 1169 // Verify internal calls. 1170 verify(getServices().iactivityManager).updateDeviceOwner( 1171 eq(admin1.getPackageName())); 1172 1173 verify(mContext.spiedContext).sendBroadcastAsUser( 1174 MockUtils.checkIntentAction(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED), 1175 MockUtils.checkUserHandle(UserHandle.USER_SYSTEM)); 1176 } 1177 checkGetDeviceOwnerInfoApi(DevicePolicyManager dpm, boolean hasDeviceOwner)1178 private void checkGetDeviceOwnerInfoApi(DevicePolicyManager dpm, boolean hasDeviceOwner) { 1179 final int origCallingUser = mContext.binder.callingUid; 1180 final List origPermissions = new ArrayList(mContext.callerPermissions); 1181 mContext.callerPermissions.clear(); 1182 1183 mContext.callerPermissions.add(permission.MANAGE_USERS); 1184 1185 mContext.binder.callingUid = Process.SYSTEM_UID; 1186 1187 // TODO Test getDeviceOwnerName() too. To do so, we need to change 1188 // DPMS.getApplicationLabel() because Context.createPackageContextAsUser() is not mockable. 1189 if (hasDeviceOwner) { 1190 assertThat(dpm.isDeviceOwnerApp(admin1.getPackageName())).isTrue(); 1191 assertThat(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())).isTrue(); 1192 assertThat(dpm.getDeviceOwnerComponentOnCallingUser()).isEqualTo(admin1); 1193 1194 assertThat(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())).isTrue(); 1195 assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isEqualTo(admin1); 1196 assertThat(dpm.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_SYSTEM); 1197 } else { 1198 assertThat(dpm.isDeviceOwnerApp(admin1.getPackageName())).isFalse(); 1199 assertThat(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())).isFalse(); 1200 assertThat(dpm.getDeviceOwnerComponentOnCallingUser()).isEqualTo(null); 1201 1202 assertThat(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())).isFalse(); 1203 assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isEqualTo(null); 1204 assertThat(dpm.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_NULL); 1205 } 1206 1207 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 1208 if (hasDeviceOwner) { 1209 assertThat(dpm.isDeviceOwnerApp(admin1.getPackageName())).isTrue(); 1210 assertThat(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())).isTrue(); 1211 assertThat(dpm.getDeviceOwnerComponentOnCallingUser()).isEqualTo(admin1); 1212 1213 assertThat(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())).isTrue(); 1214 assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isEqualTo(admin1); 1215 assertThat(dpm.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_SYSTEM); 1216 } else { 1217 assertThat(dpm.isDeviceOwnerApp(admin1.getPackageName())).isFalse(); 1218 assertThat(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())).isFalse(); 1219 assertThat(dpm.getDeviceOwnerComponentOnCallingUser()).isEqualTo(null); 1220 1221 assertThat(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())).isFalse(); 1222 assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isEqualTo(null); 1223 assertThat(dpm.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_NULL); 1224 } 1225 1226 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 1227 // Still with MANAGE_USERS. 1228 assertThat(dpm.isDeviceOwnerApp(admin1.getPackageName())).isFalse(); 1229 assertThat(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())).isFalse(); 1230 assertThat(dpm.getDeviceOwnerComponentOnCallingUser()).isEqualTo(null); 1231 1232 if (hasDeviceOwner) { 1233 assertThat(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())).isTrue(); 1234 assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isEqualTo(admin1); 1235 assertThat(dpm.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_SYSTEM); 1236 } else { 1237 assertThat(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())).isFalse(); 1238 assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isEqualTo(null); 1239 assertThat(dpm.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_NULL); 1240 } 1241 1242 mContext.binder.callingUid = Process.SYSTEM_UID; 1243 mContext.callerPermissions.remove(permission.MANAGE_USERS); 1244 // System can still call "OnAnyUser" without MANAGE_USERS. 1245 if (hasDeviceOwner) { 1246 assertThat(dpm.isDeviceOwnerApp(admin1.getPackageName())).isTrue(); 1247 assertThat(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())).isTrue(); 1248 assertThat(dpm.getDeviceOwnerComponentOnCallingUser()).isEqualTo(admin1); 1249 1250 assertThat(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())).isTrue(); 1251 assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isEqualTo(admin1); 1252 assertThat(dpm.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_SYSTEM); 1253 } else { 1254 assertThat(dpm.isDeviceOwnerApp(admin1.getPackageName())).isFalse(); 1255 assertThat(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())).isFalse(); 1256 assertThat(dpm.getDeviceOwnerComponentOnCallingUser()).isEqualTo(null); 1257 1258 assertThat(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())).isFalse(); 1259 assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isEqualTo(null); 1260 assertThat(dpm.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_NULL); 1261 } 1262 1263 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 1264 // Still no MANAGE_USERS. 1265 if (hasDeviceOwner) { 1266 assertThat(dpm.isDeviceOwnerApp(admin1.getPackageName())).isTrue(); 1267 assertThat(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())).isTrue(); 1268 assertThat(dpm.getDeviceOwnerComponentOnCallingUser()).isEqualTo(admin1); 1269 } else { 1270 assertThat(dpm.isDeviceOwnerApp(admin1.getPackageName())).isFalse(); 1271 assertThat(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())).isFalse(); 1272 assertThat(dpm.getDeviceOwnerComponentOnCallingUser()).isEqualTo(null); 1273 } 1274 1275 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 1276 () -> dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())); 1277 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 1278 dpm::getDeviceOwnerComponentOnAnyUser); 1279 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 1280 dpm::getDeviceOwnerUserId); 1281 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 1282 dpm::getDeviceOwnerNameOnAnyUser); 1283 1284 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 1285 // Still no MANAGE_USERS. 1286 assertThat(dpm.isDeviceOwnerApp(admin1.getPackageName())).isFalse(); 1287 assertThat(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())).isFalse(); 1288 assertThat(dpm.getDeviceOwnerComponentOnCallingUser()).isEqualTo(null); 1289 1290 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 1291 () -> dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())); 1292 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 1293 dpm::getDeviceOwnerComponentOnAnyUser); 1294 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 1295 dpm::getDeviceOwnerUserId); 1296 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 1297 dpm::getDeviceOwnerNameOnAnyUser); 1298 1299 // Restore. 1300 mContext.binder.callingUid = origCallingUser; 1301 mContext.callerPermissions.addAll(origPermissions); 1302 } 1303 1304 1305 /** 1306 * Test for: {@link DevicePolicyManager#setDeviceOwner} Package doesn't exist. 1307 */ 1308 @Test testSetDeviceOwner_noSuchPackage()1309 public void testSetDeviceOwner_noSuchPackage() { 1310 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 1311 mContext.callerPermissions.add(permission.MANAGE_USERS); 1312 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 1313 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); 1314 1315 // Call from a process on the system user. 1316 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 1317 1318 assertExpectException(IllegalArgumentException.class, 1319 /* messageRegex= */ "Invalid component", 1320 () -> dpm.setDeviceOwner(new ComponentName("a.b.c", ".def"))); 1321 } 1322 1323 @Test testSetDeviceOwner_failures()1324 public void testSetDeviceOwner_failures() throws Exception { 1325 // TODO Test more failure cases. Basically test all chacks in enforceCanSetDeviceOwner(). 1326 // Package doesn't exist and caller is not system 1327 assertExpectException(SecurityException.class, 1328 /* messageRegex= */ "Calling identity is not authorized", 1329 () -> dpm.setDeviceOwner(admin1, "owner-name", UserHandle.USER_SYSTEM)); 1330 1331 // Package exists, but caller is not system 1332 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 1333 assertExpectException(SecurityException.class, 1334 /* messageRegex= */ "Calling identity is not authorized", 1335 () -> dpm.setDeviceOwner(admin1, "owner-name", UserHandle.USER_SYSTEM)); 1336 } 1337 1338 @Test testClearDeviceOwner()1339 public void testClearDeviceOwner() throws Exception { 1340 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 1341 mContext.callerPermissions.add(permission.MANAGE_USERS); 1342 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 1343 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); 1344 1345 // Set admin1 as a DA to the secondary user. 1346 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID); 1347 1348 dpm.setActiveAdmin(admin1, /* replace =*/ false); 1349 1350 // Set admin 1 as the DO to the system user. 1351 1352 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 1353 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 1354 dpm.setActiveAdmin(admin1, /* replace =*/ false); 1355 assertThat(dpm.setDeviceOwner(admin1, "owner-name")).isTrue(); 1356 1357 // Verify internal calls. 1358 verify(getServices().iactivityManager, times(1)).updateDeviceOwner( 1359 eq(admin1.getPackageName())); 1360 1361 assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isEqualTo(admin1); 1362 1363 dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADD_USER); 1364 when(getServices().userManager.hasUserRestriction(eq(UserManager.DISALLOW_ADD_USER), 1365 MockUtils.checkUserHandle(UserHandle.USER_SYSTEM))).thenReturn(true); 1366 1367 assertThat(dpm.isAdminActive(admin1)).isTrue(); 1368 assertThat(dpm.isRemovingAdmin(admin1, UserHandle.USER_SYSTEM)).isFalse(); 1369 1370 // Set up other mocks. 1371 when(getServices().userManager.getUserRestrictions()).thenReturn(new Bundle()); 1372 1373 // Now call clear. 1374 doReturn(DpmMockContext.CALLER_SYSTEM_USER_UID).when(getServices().packageManager). 1375 getPackageUidAsUser(eq(admin1.getPackageName()), anyInt()); 1376 1377 // But first pretend the user is locked. Then it should fail. 1378 when(getServices().userManager.isUserUnlocked(anyInt())).thenReturn(false); 1379 assertExpectException(IllegalStateException.class, 1380 /* messageRegex= */ "User must be running and unlocked", 1381 () -> dpm.clearDeviceOwnerApp(admin1.getPackageName())); 1382 1383 when(getServices().userManager.isUserUnlocked(anyInt())).thenReturn(true); 1384 dpm.clearDeviceOwnerApp(admin1.getPackageName()); 1385 1386 // Now DO shouldn't be set. 1387 assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isNull(); 1388 1389 verify(getServices().userManager).setUserRestriction(eq(UserManager.DISALLOW_ADD_USER), 1390 eq(false), 1391 MockUtils.checkUserHandle(UserHandle.USER_SYSTEM)); 1392 1393 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 1394 eq(UserHandle.USER_SYSTEM), MockUtils.checkUserRestrictions(), 1395 MockUtils.checkUserRestrictions(UserHandle.USER_SYSTEM), eq(true)); 1396 1397 verify(getServices().usageStatsManagerInternal).setActiveAdminApps( 1398 null, UserHandle.USER_SYSTEM); 1399 1400 assertThat(dpm.isAdminActiveAsUser(admin1, UserHandle.USER_SYSTEM)).isFalse(); 1401 1402 // ACTION_DEVICE_OWNER_CHANGED should be sent twice, once for setting the device owner 1403 // and once for clearing it. 1404 verify(mContext.spiedContext, times(2)).sendBroadcastAsUser( 1405 MockUtils.checkIntentAction(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED), 1406 MockUtils.checkUserHandle(UserHandle.USER_SYSTEM)); 1407 // TODO Check other calls. 1408 } 1409 1410 @Test testDeviceOwnerBackupActivateDeactivate()1411 public void testDeviceOwnerBackupActivateDeactivate() throws Exception { 1412 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 1413 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 1414 1415 // Set admin1 as a DA to the secondary user. 1416 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 1417 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 1418 dpm.setActiveAdmin(admin1, /* replace =*/ false); 1419 assertThat(dpm.setDeviceOwner(admin1, "owner-name")).isTrue(); 1420 1421 verify(getServices().ibackupManager, times(1)).setBackupServiceActive( 1422 eq(UserHandle.USER_SYSTEM), eq(false)); 1423 1424 dpm.clearDeviceOwnerApp(admin1.getPackageName()); 1425 1426 verify(getServices().ibackupManager, times(1)).setBackupServiceActive( 1427 eq(UserHandle.USER_SYSTEM), eq(true)); 1428 } 1429 1430 @Test testProfileOwnerBackupActivateDeactivate()1431 public void testProfileOwnerBackupActivateDeactivate() throws Exception { 1432 setAsProfileOwner(admin1); 1433 1434 verify(getServices().ibackupManager, times(1)).setBackupServiceActive( 1435 eq(CALLER_USER_HANDLE), eq(false)); 1436 1437 dpm.clearProfileOwner(admin1); 1438 1439 verify(getServices().ibackupManager, times(1)).setBackupServiceActive( 1440 eq(CALLER_USER_HANDLE), eq(true)); 1441 } 1442 1443 @Test testClearDeviceOwner_fromDifferentUser()1444 public void testClearDeviceOwner_fromDifferentUser() throws Exception { 1445 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 1446 mContext.callerPermissions.add(permission.MANAGE_USERS); 1447 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 1448 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); 1449 1450 // Set admin1 as a DA to the secondary user. 1451 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID); 1452 1453 dpm.setActiveAdmin(admin1, /* replace =*/ false); 1454 1455 // Set admin 1 as the DO to the system user. 1456 1457 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 1458 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 1459 dpm.setActiveAdmin(admin1, /* replace =*/ false); 1460 assertThat(dpm.setDeviceOwner(admin1, "owner-name")).isTrue(); 1461 1462 // Verify internal calls. 1463 verify(getServices().iactivityManager, times(1)).updateDeviceOwner( 1464 eq(admin1.getPackageName())); 1465 1466 assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isEqualTo(admin1); 1467 1468 // Now call clear from the secondary user, which should throw. 1469 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 1470 1471 // Now call clear. 1472 doReturn(DpmMockContext.CALLER_UID).when(getServices().packageManager).getPackageUidAsUser( 1473 eq(admin1.getPackageName()), 1474 anyInt()); 1475 assertExpectException(SecurityException.class, 1476 /* messageRegex =*/ "clearDeviceOwner can only be called by the device owner", 1477 () -> dpm.clearDeviceOwnerApp(admin1.getPackageName())); 1478 1479 // DO shouldn't be removed. 1480 assertThat(dpm.isDeviceManaged()).isTrue(); 1481 } 1482 1483 /** 1484 * Test for: {@link DevicePolicyManager#clearDeviceOwnerApp(String)} 1485 * 1486 * Validates that when the device owner is removed, the reset password token is cleared 1487 */ 1488 @Test testClearDeviceOwner_clearResetPasswordToken()1489 public void testClearDeviceOwner_clearResetPasswordToken() throws Exception { 1490 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 1491 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 1492 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 1493 1494 // Install admin1 on system user 1495 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 1496 1497 // Set admin1 to active admin and device owner 1498 dpm.setActiveAdmin(admin1, /* replace =*/ false); 1499 dpm.setDeviceOwner(admin1, null, UserHandle.USER_SYSTEM); 1500 1501 // Add reset password token 1502 final long handle = 12000; 1503 final byte[] token = new byte[32]; 1504 when(getServices().lockPatternUtils.addEscrowToken(eq(token), eq(UserHandle.USER_SYSTEM), 1505 nullable(EscrowTokenStateChangeCallback.class))) 1506 .thenReturn(handle); 1507 assertThat(dpm.setResetPasswordToken(admin1, token)).isTrue(); 1508 1509 // Assert reset password token is active 1510 when(getServices().lockPatternUtils.isEscrowTokenActive(eq(handle), 1511 eq(UserHandle.USER_SYSTEM))) 1512 .thenReturn(true); 1513 assertThat(dpm.isResetPasswordTokenActive(admin1)).isTrue(); 1514 1515 // Remove the device owner 1516 dpm.clearDeviceOwnerApp(admin1.getPackageName()); 1517 1518 // Verify password reset password token was removed 1519 verify(getServices().lockPatternUtils).removeEscrowToken(eq(handle), 1520 eq(UserHandle.USER_SYSTEM)); 1521 } 1522 1523 @Test testSetProfileOwner()1524 public void testSetProfileOwner() throws Exception { 1525 setAsProfileOwner(admin1); 1526 1527 // PO admin can't be deactivated. 1528 dpm.removeActiveAdmin(admin1); 1529 assertThat(dpm.isAdminActive(admin1)).isTrue(); 1530 1531 // Try setting DO on the same user, which should fail. 1532 setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID); 1533 mServiceContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 1534 runAsCaller(mServiceContext, dpms, dpm -> { 1535 dpm.setActiveAdmin(admin2, /* refreshing= */ true, CALLER_USER_HANDLE); 1536 assertExpectException(IllegalStateException.class, 1537 /* messageRegex= */ "already has a profile owner", 1538 () -> dpm.setDeviceOwner(admin2, "owner-name", 1539 CALLER_USER_HANDLE)); 1540 }); 1541 } 1542 1543 @Test testClearProfileOwner()1544 public void testClearProfileOwner() throws Exception { 1545 setAsProfileOwner(admin1); 1546 1547 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 1548 1549 assertThat(dpm.isProfileOwnerApp(admin1.getPackageName())).isTrue(); 1550 assertThat(dpm.isRemovingAdmin(admin1, CALLER_USER_HANDLE)).isFalse(); 1551 1552 // First try when the user is locked, which should fail. 1553 when(getServices().userManager.isUserUnlocked(anyInt())) 1554 .thenReturn(false); 1555 assertExpectException(IllegalStateException.class, 1556 /* messageRegex= */ "User must be running and unlocked", 1557 () -> dpm.clearProfileOwner(admin1)); 1558 1559 // Clear, really. 1560 when(getServices().userManager.isUserUnlocked(anyInt())).thenReturn(true); 1561 dpm.clearProfileOwner(admin1); 1562 1563 // Check 1564 assertThat(dpm.isProfileOwnerApp(admin1.getPackageName())).isFalse(); 1565 assertThat(dpm.isAdminActiveAsUser(admin1, CALLER_USER_HANDLE)).isFalse(); 1566 verify(getServices().usageStatsManagerInternal).setActiveAdminApps( 1567 null, CALLER_USER_HANDLE); 1568 } 1569 1570 @Test testSetProfileOwner_failures()1571 public void testSetProfileOwner_failures() throws Exception { 1572 // TODO Test more failure cases. Basically test all chacks in enforceCanSetProfileOwner(). 1573 // Package doesn't exist and caller is not system 1574 assertExpectException(SecurityException.class, 1575 /* messageRegex= */ "Calling identity is not authorized", 1576 () -> dpm.setProfileOwner(admin1, "owner-name", UserHandle.USER_SYSTEM)); 1577 1578 // Package exists, but caller is not system 1579 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 1580 assertExpectException(SecurityException.class, 1581 /* messageRegex= */ "Calling identity is not authorized", 1582 () -> dpm.setProfileOwner(admin1, "owner-name", UserHandle.USER_SYSTEM)); 1583 } 1584 1585 @Test testGetDeviceOwnerAdminLocked()1586 public void testGetDeviceOwnerAdminLocked() throws Exception { 1587 checkDeviceOwnerWithMultipleDeviceAdmins(); 1588 } 1589 1590 // This method is used primarily for testDeviceOwnerMigration. checkDeviceOwnerWithMultipleDeviceAdmins()1591 private void checkDeviceOwnerWithMultipleDeviceAdmins() throws Exception { 1592 // In ths test, we use 3 users (system + 2 secondary users), set some device admins to them, 1593 // set admin3 on USER_SYSTEM as DO, then call getDeviceOwnerAdminLocked() to 1594 // make sure it gets the right component from the right user. 1595 1596 final int ANOTHER_USER_ID = 100; 1597 final int ANOTHER_ADMIN_UID = UserHandle.getUid(ANOTHER_USER_ID, 456); 1598 1599 getServices().addUser(ANOTHER_USER_ID, 0, ""); // Add one more user. 1600 1601 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 1602 mContext.callerPermissions.add(permission.MANAGE_USERS); 1603 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 1604 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); 1605 1606 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 1607 1608 // Make sure the admin package is installed to each user. 1609 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 1610 setUpPackageManagerForAdmin(admin3, DpmMockContext.CALLER_SYSTEM_USER_UID); 1611 1612 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID); 1613 setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID); 1614 1615 setUpPackageManagerForAdmin(admin2, ANOTHER_ADMIN_UID); 1616 1617 // Set active admins to the users. 1618 dpm.setActiveAdmin(admin1, /* replace =*/ false); 1619 dpm.setActiveAdmin(admin3, /* replace =*/ false); 1620 1621 dpm.setActiveAdmin(admin1, /* replace =*/ false, CALLER_USER_HANDLE); 1622 dpm.setActiveAdmin(admin2, /* replace =*/ false, CALLER_USER_HANDLE); 1623 1624 dpm.setActiveAdmin(admin2, /* replace =*/ false, ANOTHER_USER_ID); 1625 1626 // Set DO on the system user which is only allowed during first boot. 1627 setUserSetupCompleteForUser(false, UserHandle.USER_SYSTEM); 1628 assertThat(dpm.setDeviceOwner(admin3, "owner-name", UserHandle.USER_SYSTEM)).isTrue(); 1629 assertThat(dpms.getDeviceOwnerComponent(/* callingUserOnly =*/ false)).isEqualTo(admin3); 1630 1631 // Then check getDeviceOwnerAdminLocked(). 1632 ActiveAdmin deviceOwner = getDeviceOwner(); 1633 assertThat(deviceOwner.info.getComponent()).isEqualTo(admin3); 1634 assertThat(deviceOwner.getUid()).isEqualTo(DpmMockContext.CALLER_SYSTEM_USER_UID); 1635 } 1636 1637 /** 1638 * This essentially tests 1639 * {@code DevicePolicyManagerService.findOwnerComponentIfNecessaryLocked()}. (which is 1640 * private.) 1641 * 1642 * We didn't use to persist the DO component class name, but now we do, and the above method 1643 * finds the right component from a package name upon migration. 1644 */ 1645 @Test testDeviceOwnerMigration()1646 public void testDeviceOwnerMigration() throws Exception { 1647 checkDeviceOwnerWithMultipleDeviceAdmins(); 1648 1649 // Overwrite the device owner setting and clears the class name. 1650 dpms.mOwners.setDeviceOwner( 1651 new ComponentName(admin2.getPackageName(), ""), 1652 "owner-name", CALLER_USER_HANDLE); 1653 dpms.mOwners.writeDeviceOwner(); 1654 1655 // Make sure the DO component name doesn't have a class name. 1656 assertThat(dpms.getDeviceOwnerComponent(/* callingUserOnly= */ false).getClassName()) 1657 .isEmpty(); 1658 1659 // Then create a new DPMS to have it load the settings from files. 1660 when(getServices().userManager.getUserRestrictions(any(UserHandle.class))) 1661 .thenReturn(new Bundle()); 1662 initializeDpms(); 1663 1664 // Now the DO component name is a full name. 1665 // *BUT* because both admin1 and admin2 belong to the same package, we think admin1 is the 1666 // DO. 1667 assertThat(dpms.getDeviceOwnerComponent(/* callingUserOnly =*/ false)).isEqualTo(admin1); 1668 } 1669 1670 @Test testSetGetApplicationRestriction()1671 public void testSetGetApplicationRestriction() { 1672 setAsProfileOwner(admin1); 1673 mContext.packageName = admin1.getPackageName(); 1674 1675 { 1676 Bundle rest = new Bundle(); 1677 rest.putString("KEY_STRING", "Foo1"); 1678 dpm.setApplicationRestrictions(admin1, "pkg1", rest); 1679 } 1680 1681 { 1682 Bundle rest = new Bundle(); 1683 rest.putString("KEY_STRING", "Foo2"); 1684 dpm.setApplicationRestrictions(admin1, "pkg2", rest); 1685 } 1686 1687 { 1688 Bundle returned = dpm.getApplicationRestrictions(admin1, "pkg1"); 1689 assertThat(returned).isNotNull(); 1690 assertThat(returned.size()).isEqualTo(1); 1691 assertThat("Foo1").isEqualTo(returned.get("KEY_STRING")); 1692 } 1693 1694 { 1695 Bundle returned = dpm.getApplicationRestrictions(admin1, "pkg2"); 1696 assertThat(returned).isNotNull(); 1697 assertThat(returned.size()).isEqualTo(1); 1698 assertThat("Foo2").isEqualTo(returned.get("KEY_STRING")); 1699 } 1700 1701 dpm.setApplicationRestrictions(admin1, "pkg2", new Bundle()); 1702 assertThat(dpm.getApplicationRestrictions(admin1, "pkg2").size()).isEqualTo(0); 1703 } 1704 1705 /** 1706 * Setup a package in the package manager mock for {@link DpmMockContext#CALLER_USER_HANDLE}. 1707 * Useful for faking installed applications. 1708 * 1709 * @param packageName the name of the package to be setup 1710 * @param appId the application ID to be given to the package 1711 * @return the UID of the package as known by the mock package manager 1712 */ setupPackageInPackageManager(final String packageName, final int appId)1713 private int setupPackageInPackageManager(final String packageName, final int appId) 1714 throws Exception { 1715 return setupPackageInPackageManager(packageName, CALLER_USER_HANDLE, appId, 1716 ApplicationInfo.FLAG_HAS_CODE); 1717 } 1718 1719 /** 1720 * Setup a package in the package manager mock. Useful for faking installed applications. 1721 * 1722 * @param packageName the name of the package to be setup 1723 * @param userId the user id where the package will be "installed" 1724 * @param appId the application ID to be given to the package 1725 * @param flags flags to set in the ApplicationInfo for this package 1726 * @return the UID of the package as known by the mock package manager 1727 */ setupPackageInPackageManager(final String packageName, int userId, final int appId, int flags)1728 private int setupPackageInPackageManager(final String packageName, int userId, final int appId, 1729 int flags) throws Exception { 1730 final int uid = UserHandle.getUid(userId, appId); 1731 // Make the PackageManager return the package instead of throwing NameNotFoundException 1732 final PackageInfo pi = new PackageInfo(); 1733 pi.applicationInfo = new ApplicationInfo(); 1734 pi.applicationInfo.flags = flags; 1735 doReturn(pi).when(getServices().ipackageManager).getPackageInfo( 1736 eq(packageName), 1737 anyInt(), 1738 eq(userId)); 1739 doReturn(pi.applicationInfo).when(getServices().ipackageManager).getApplicationInfo( 1740 eq(packageName), 1741 anyInt(), 1742 eq(userId)); 1743 doReturn(true).when(getServices().ipackageManager).isPackageAvailable(packageName, userId); 1744 // Setup application UID with the PackageManager 1745 doReturn(uid).when(getServices().packageManager).getPackageUidAsUser( 1746 eq(packageName), 1747 eq(userId)); 1748 // Associate packageName to uid 1749 doReturn(packageName).when(getServices().ipackageManager).getNameForUid(eq(uid)); 1750 doReturn(new String[]{packageName}) 1751 .when(getServices().ipackageManager).getPackagesForUid(eq(uid)); 1752 return uid; 1753 } 1754 1755 @Test testCertificateDisclosure()1756 public void testCertificateDisclosure() throws Exception { 1757 final int userId = CALLER_USER_HANDLE; 1758 final UserHandle user = UserHandle.of(userId); 1759 1760 mContext.applicationInfo = new ApplicationInfo(); 1761 mContext.callerPermissions.add(permission.MANAGE_USERS); 1762 mContext.packageName = "com.android.frameworks.servicestests"; 1763 getServices().addPackageContext(user, mContext); 1764 when(mContext.resources.getColor(anyInt(), anyObject())).thenReturn(Color.WHITE); 1765 1766 StringParceledListSlice oneCert = asSlice(new String[] {"1"}); 1767 StringParceledListSlice fourCerts = asSlice(new String[] {"1", "2", "3", "4"}); 1768 1769 final String TEST_STRING = "Test for exactly 2 certs out of 4"; 1770 doReturn(TEST_STRING).when(mContext.resources).getQuantityText(anyInt(), eq(2)); 1771 1772 // Given that we have exactly one certificate installed, 1773 when(getServices().keyChainConnection.getService().getUserCaAliases()).thenReturn(oneCert); 1774 // when that certificate is approved, 1775 dpms.approveCaCert(oneCert.getList().get(0), userId, true); 1776 // a notification should not be shown. 1777 verify(getServices().notificationManager, timeout(1000)) 1778 .cancelAsUser(anyString(), anyInt(), eq(user)); 1779 1780 // Given that we have four certificates installed, 1781 when(getServices().keyChainConnection.getService().getUserCaAliases()) 1782 .thenReturn(fourCerts); 1783 // when two of them are approved (one of them approved twice hence no action), 1784 dpms.approveCaCert(fourCerts.getList().get(0), userId, true); 1785 dpms.approveCaCert(fourCerts.getList().get(1), userId, true); 1786 // a notification should be shown saying that there are two certificates left to approve. 1787 verify(getServices().notificationManager, timeout(1000)) 1788 .notifyAsUser(anyString(), anyInt(), argThat(hasExtra(EXTRA_TITLE, 1789 TEST_STRING 1790 )), eq(user)); 1791 } 1792 1793 @Test testRemoveCredentialManagementApp()1794 public void testRemoveCredentialManagementApp() throws Exception { 1795 final String packageName = "com.test.cred.mng"; 1796 Intent intent = new Intent(Intent.ACTION_PACKAGE_REMOVED); 1797 intent.setData(Uri.parse("package:" + packageName)); 1798 dpms.mReceiver.setPendingResult( 1799 new BroadcastReceiver.PendingResult(Activity.RESULT_OK, 1800 "resultData", 1801 /* resultExtras= */ null, 1802 BroadcastReceiver.PendingResult.TYPE_UNREGISTERED, 1803 /* ordered= */ true, 1804 /* sticky= */ false, 1805 /* token= */ null, 1806 CALLER_USER_HANDLE, 1807 /* flags= */ 0)); 1808 when(getServices().keyChainConnection.getService().hasCredentialManagementApp()) 1809 .thenReturn(true); 1810 when(getServices().keyChainConnection.getService().getCredentialManagementAppPackageName()) 1811 .thenReturn(packageName); 1812 1813 dpms.mReceiver.onReceive(mContext, intent); 1814 1815 flushTasks(dpms); 1816 verify(getServices().keyChainConnection.getService()).hasCredentialManagementApp(); 1817 verify(getServices().keyChainConnection.getService()).removeCredentialManagementApp(); 1818 } 1819 1820 /** 1821 * Simple test for delegate set/get and general delegation. Tests verifying that delegated 1822 * privileges can acually be exercised by a delegate are not covered here. 1823 */ 1824 @Test testDelegation()1825 public void testDelegation() throws Exception { 1826 setAsProfileOwner(admin1); 1827 1828 final int userHandle = CALLER_USER_HANDLE; 1829 1830 // Given two packages 1831 final String CERT_DELEGATE = "com.delegate.certs"; 1832 final String RESTRICTIONS_DELEGATE = "com.delegate.apprestrictions"; 1833 final int CERT_DELEGATE_UID = setupPackageInPackageManager(CERT_DELEGATE, 20988); 1834 final int RESTRICTIONS_DELEGATE_UID = setupPackageInPackageManager(RESTRICTIONS_DELEGATE, 1835 20989); 1836 1837 // On delegation 1838 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 1839 mContext.packageName = admin1.getPackageName(); 1840 dpm.setCertInstallerPackage(admin1, CERT_DELEGATE); 1841 dpm.setApplicationRestrictionsManagingPackage(admin1, RESTRICTIONS_DELEGATE); 1842 1843 // DPMS correctly stores and retrieves the delegates 1844 DevicePolicyData policy = dpms.mUserData.get(userHandle); 1845 assertThat(policy.mDelegationMap.size()).isEqualTo(2); 1846 MoreAsserts.assertContentsInAnyOrder(policy.mDelegationMap.get(CERT_DELEGATE), 1847 DELEGATION_CERT_INSTALL); 1848 MoreAsserts.assertContentsInAnyOrder(dpm.getDelegatedScopes(admin1, CERT_DELEGATE), 1849 DELEGATION_CERT_INSTALL); 1850 assertThat(dpm.getCertInstallerPackage(admin1)).isEqualTo(CERT_DELEGATE); 1851 MoreAsserts.assertContentsInAnyOrder(policy.mDelegationMap.get(RESTRICTIONS_DELEGATE), 1852 DELEGATION_APP_RESTRICTIONS); 1853 MoreAsserts.assertContentsInAnyOrder(dpm.getDelegatedScopes(admin1, RESTRICTIONS_DELEGATE), 1854 DELEGATION_APP_RESTRICTIONS); 1855 assertThat(dpm.getApplicationRestrictionsManagingPackage(admin1)) 1856 .isEqualTo(RESTRICTIONS_DELEGATE); 1857 1858 // On calling install certificate APIs from an unauthorized process 1859 mContext.binder.callingUid = RESTRICTIONS_DELEGATE_UID; 1860 mContext.packageName = RESTRICTIONS_DELEGATE; 1861 1862 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 1863 () -> dpm.installCaCert(null, null)); 1864 1865 // On calling install certificate APIs from an authorized process 1866 mContext.binder.callingUid = CERT_DELEGATE_UID; 1867 mContext.packageName = CERT_DELEGATE; 1868 1869 // DPMS executes without a SecurityException 1870 try { 1871 dpm.installCaCert(null, null); 1872 } catch (SecurityException unexpected) { 1873 fail("Threw SecurityException on authorized access"); 1874 } catch (NullPointerException expected) { 1875 } 1876 1877 // On removing a delegate 1878 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 1879 mContext.packageName = admin1.getPackageName(); 1880 dpm.setCertInstallerPackage(admin1, null); 1881 1882 // DPMS does not allow access to ex-delegate 1883 mContext.binder.callingUid = CERT_DELEGATE_UID; 1884 mContext.packageName = CERT_DELEGATE; 1885 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 1886 () -> dpm.installCaCert(null, null)); 1887 1888 // But still allows access to other existing delegates 1889 mContext.binder.callingUid = RESTRICTIONS_DELEGATE_UID; 1890 mContext.packageName = RESTRICTIONS_DELEGATE; 1891 try { 1892 dpm.getApplicationRestrictions(null, "pkg"); 1893 } catch (SecurityException expected) { 1894 fail("Threw SecurityException on authorized access"); 1895 } 1896 } 1897 1898 @Test testApplicationRestrictionsManagingApp()1899 public void testApplicationRestrictionsManagingApp() throws Exception { 1900 setAsProfileOwner(admin1); 1901 1902 final String nonExistAppRestrictionsManagerPackage = "com.google.app.restrictions.manager2"; 1903 final String appRestrictionsManagerPackage = "com.google.app.restrictions.manager"; 1904 final String nonDelegateExceptionMessageRegex = 1905 "Caller with uid \\d+ is not com.google.app.restrictions.manager"; 1906 final int appRestrictionsManagerAppId = 20987; 1907 final int appRestrictionsManagerUid = setupPackageInPackageManager( 1908 appRestrictionsManagerPackage, appRestrictionsManagerAppId); 1909 1910 // appRestrictionsManager package shouldn't be able to manage restrictions as the PO hasn't 1911 // delegated that permission yet. 1912 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 1913 mContext.packageName = admin1.getPackageName(); 1914 assertThat(dpm.isCallerApplicationRestrictionsManagingPackage()).isFalse(); 1915 final Bundle rest = new Bundle(); 1916 rest.putString("KEY_STRING", "Foo1"); 1917 assertExpectException(SecurityException.class, INVALID_CALLING_IDENTITY_MSG, 1918 () -> dpm.setApplicationRestrictions(null, "pkg1", rest)); 1919 1920 // Check via the profile owner that no restrictions were set. 1921 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 1922 mContext.packageName = admin1.getPackageName(); 1923 assertThat(dpm.getApplicationRestrictions(admin1, "pkg1").size()).isEqualTo(0); 1924 1925 // Check the API does not allow setting a non-existent package 1926 assertExpectException(PackageManager.NameNotFoundException.class, 1927 /* messageRegex= */ nonExistAppRestrictionsManagerPackage, 1928 () -> dpm.setApplicationRestrictionsManagingPackage( 1929 admin1, nonExistAppRestrictionsManagerPackage)); 1930 1931 // Let appRestrictionsManagerPackage manage app restrictions 1932 dpm.setApplicationRestrictionsManagingPackage(admin1, appRestrictionsManagerPackage); 1933 assertThat(dpm.getApplicationRestrictionsManagingPackage(admin1)) 1934 .isEqualTo(appRestrictionsManagerPackage); 1935 1936 // Now that package should be able to set and retrieve app restrictions. 1937 mContext.binder.callingUid = appRestrictionsManagerUid; 1938 mContext.packageName = appRestrictionsManagerPackage; 1939 assertThat(dpm.isCallerApplicationRestrictionsManagingPackage()).isTrue(); 1940 dpm.setApplicationRestrictions(null, "pkg1", rest); 1941 Bundle returned = dpm.getApplicationRestrictions(null, "pkg1"); 1942 assertThat(returned.size()).isEqualTo(1); 1943 assertThat(returned.get("KEY_STRING")).isEqualTo("Foo1"); 1944 1945 // The same app running on a separate user shouldn't be able to manage app restrictions. 1946 mContext.binder.callingUid = UserHandle.getUid( 1947 UserHandle.USER_SYSTEM, appRestrictionsManagerAppId); 1948 assertThat(dpm.isCallerApplicationRestrictionsManagingPackage()).isFalse(); 1949 assertExpectException(SecurityException.class, nonDelegateExceptionMessageRegex, 1950 () -> dpm.setApplicationRestrictions(null, "pkg1", rest)); 1951 1952 // The DPM is still able to manage app restrictions, even if it allowed another app to do it 1953 // too. 1954 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 1955 mContext.packageName = admin1.getPackageName(); 1956 assertThat(dpm.getApplicationRestrictions(admin1, "pkg1")).isEqualTo(returned); 1957 dpm.setApplicationRestrictions(admin1, "pkg1", null); 1958 assertThat(dpm.getApplicationRestrictions(admin1, "pkg1").size()).isEqualTo(0); 1959 1960 // Removing the ability for the package to manage app restrictions. 1961 dpm.setApplicationRestrictionsManagingPackage(admin1, null); 1962 assertThat(dpm.getApplicationRestrictionsManagingPackage(admin1)).isNull(); 1963 mContext.binder.callingUid = appRestrictionsManagerUid; 1964 mContext.packageName = appRestrictionsManagerPackage; 1965 assertThat(dpm.isCallerApplicationRestrictionsManagingPackage()).isFalse(); 1966 assertExpectException(SecurityException.class, INVALID_CALLING_IDENTITY_MSG, 1967 () -> dpm.setApplicationRestrictions(null, "pkg1", null)); 1968 } 1969 1970 @Test testSetUserRestriction_asDo()1971 public void testSetUserRestriction_asDo() throws Exception { 1972 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 1973 mContext.callerPermissions.add(permission.MANAGE_USERS); 1974 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 1975 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); 1976 1977 // First, set DO. 1978 1979 // Call from a process on the system user. 1980 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 1981 1982 // Make sure admin1 is installed on system user. 1983 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 1984 1985 // Call. 1986 dpm.setActiveAdmin(admin1, /* replace =*/ false, UserHandle.USER_SYSTEM); 1987 assertThat(dpm.setDeviceOwner(admin1, "owner-name", 1988 UserHandle.USER_SYSTEM)).isTrue(); 1989 1990 assertNoDeviceOwnerRestrictions(); 1991 reset(getServices().userManagerInternal); 1992 1993 dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADD_USER); 1994 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 1995 eq(UserHandle.USER_SYSTEM), 1996 MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADD_USER), 1997 MockUtils.checkUserRestrictions(UserHandle.USER_SYSTEM), eq(true)); 1998 reset(getServices().userManagerInternal); 1999 2000 dpm.addUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS); 2001 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 2002 eq(UserHandle.USER_SYSTEM), 2003 MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADD_USER), 2004 MockUtils.checkUserRestrictions(UserHandle.USER_SYSTEM, 2005 UserManager.DISALLOW_OUTGOING_CALLS), 2006 eq(true)); 2007 reset(getServices().userManagerInternal); 2008 2009 DpmTestUtils.assertRestrictions( 2010 DpmTestUtils.newRestrictions( 2011 UserManager.DISALLOW_ADD_USER, UserManager.DISALLOW_OUTGOING_CALLS), 2012 getDeviceOwner().ensureUserRestrictions() 2013 ); 2014 DpmTestUtils.assertRestrictions( 2015 DpmTestUtils.newRestrictions( 2016 UserManager.DISALLOW_ADD_USER, UserManager.DISALLOW_OUTGOING_CALLS), 2017 dpm.getUserRestrictions(admin1) 2018 ); 2019 2020 dpm.clearUserRestriction(admin1, UserManager.DISALLOW_ADD_USER); 2021 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 2022 eq(UserHandle.USER_SYSTEM), 2023 MockUtils.checkUserRestrictions(), 2024 MockUtils.checkUserRestrictions(UserHandle.USER_SYSTEM, 2025 UserManager.DISALLOW_OUTGOING_CALLS), 2026 eq(true)); 2027 reset(getServices().userManagerInternal); 2028 2029 DpmTestUtils.assertRestrictions( 2030 DpmTestUtils.newRestrictions(UserManager.DISALLOW_OUTGOING_CALLS), 2031 getDeviceOwner().ensureUserRestrictions() 2032 ); 2033 DpmTestUtils.assertRestrictions( 2034 DpmTestUtils.newRestrictions(UserManager.DISALLOW_OUTGOING_CALLS), 2035 dpm.getUserRestrictions(admin1) 2036 ); 2037 2038 dpm.clearUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS); 2039 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 2040 eq(UserHandle.USER_SYSTEM), 2041 MockUtils.checkUserRestrictions(), 2042 MockUtils.checkUserRestrictions(UserHandle.USER_SYSTEM), eq(true)); 2043 reset(getServices().userManagerInternal); 2044 2045 assertNoDeviceOwnerRestrictions(); 2046 2047 // DISALLOW_ADJUST_VOLUME and DISALLOW_UNMUTE_MICROPHONE are PO restrictions, but when 2048 // DO sets them, the scope is global. 2049 dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADJUST_VOLUME); 2050 reset(getServices().userManagerInternal); 2051 dpm.addUserRestriction(admin1, UserManager.DISALLOW_UNMUTE_MICROPHONE); 2052 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 2053 eq(UserHandle.USER_SYSTEM), 2054 MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADJUST_VOLUME, 2055 UserManager.DISALLOW_UNMUTE_MICROPHONE), 2056 MockUtils.checkUserRestrictions(UserHandle.USER_SYSTEM), eq(true)); 2057 reset(getServices().userManagerInternal); 2058 2059 dpm.clearUserRestriction(admin1, UserManager.DISALLOW_ADJUST_VOLUME); 2060 dpm.clearUserRestriction(admin1, UserManager.DISALLOW_UNMUTE_MICROPHONE); 2061 reset(getServices().userManagerInternal); 2062 2063 // More tests. 2064 dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADD_USER); 2065 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 2066 eq(UserHandle.USER_SYSTEM), 2067 MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADD_USER), 2068 MockUtils.checkUserRestrictions(UserHandle.USER_SYSTEM), eq(true)); 2069 reset(getServices().userManagerInternal); 2070 2071 dpm.addUserRestriction(admin1, UserManager.DISALLOW_FUN); 2072 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 2073 eq(UserHandle.USER_SYSTEM), 2074 MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN, 2075 UserManager.DISALLOW_ADD_USER), 2076 MockUtils.checkUserRestrictions(UserHandle.USER_SYSTEM), eq(true)); 2077 reset(getServices().userManagerInternal); 2078 2079 dpm.setCameraDisabled(admin1, true); 2080 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 2081 eq(UserHandle.USER_SYSTEM), 2082 // DISALLOW_CAMERA will be applied globally. 2083 MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN, 2084 UserManager.DISALLOW_ADD_USER, UserManager.DISALLOW_CAMERA), 2085 MockUtils.checkUserRestrictions(UserHandle.USER_SYSTEM), eq(true)); 2086 reset(getServices().userManagerInternal); 2087 } 2088 getDeviceOwner()2089 private ActiveAdmin getDeviceOwner() { 2090 ComponentName component = dpms.mOwners.getDeviceOwnerComponent(); 2091 DevicePolicyData policy = 2092 dpms.getUserData(dpms.mOwners.getDeviceOwnerUserId()); 2093 for (ActiveAdmin admin : policy.mAdminList) { 2094 if (component.equals(admin.info.getComponent())) { 2095 return admin; 2096 } 2097 } 2098 return null; 2099 } 2100 2101 @Test testDaDisallowedPolicies_SecurityException()2102 public void testDaDisallowedPolicies_SecurityException() throws Exception { 2103 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 2104 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); 2105 2106 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID, null, 2107 Build.VERSION_CODES.Q); 2108 dpm.setActiveAdmin(admin1, /* replace =*/ false, UserHandle.USER_SYSTEM); 2109 2110 2111 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 2112 boolean originalCameraDisabled = dpm.getCameraDisabled(admin1); 2113 assertExpectException(SecurityException.class, /* messageRegex= */ null, 2114 () -> dpm.setCameraDisabled(admin1, true)); 2115 assertThat(dpm.getCameraDisabled(admin1)).isEqualTo(originalCameraDisabled); 2116 2117 int originalKeyguardDisabledFeatures = dpm.getKeyguardDisabledFeatures(admin1); 2118 assertExpectException(SecurityException.class, /* messageRegex= */ null, 2119 () -> dpm.setKeyguardDisabledFeatures(admin1, 2120 DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_ALL)); 2121 assertThat(dpm.getKeyguardDisabledFeatures(admin1)) 2122 .isEqualTo(originalKeyguardDisabledFeatures); 2123 2124 long originalPasswordExpirationTimeout = dpm.getPasswordExpirationTimeout(admin1); 2125 assertExpectException(SecurityException.class, /* messageRegex= */ null, 2126 () -> dpm.setPasswordExpirationTimeout(admin1, 1234)); 2127 assertThat(dpm.getPasswordExpirationTimeout(admin1)) 2128 .isEqualTo(originalPasswordExpirationTimeout); 2129 2130 if (isDeprecatedPasswordApisSupported()) { 2131 int originalPasswordQuality = dpm.getPasswordQuality(admin1); 2132 assertExpectException(SecurityException.class, /* messageRegex= */ null, 2133 () -> dpm.setPasswordQuality(admin1, 2134 DevicePolicyManager.PASSWORD_QUALITY_NUMERIC)); 2135 assertThat(dpm.getPasswordQuality(admin1)).isEqualTo(originalPasswordQuality); 2136 } 2137 } 2138 2139 @Test testSetUserRestriction_asPo()2140 public void testSetUserRestriction_asPo() { 2141 setAsProfileOwner(admin1); 2142 2143 DpmTestUtils.assertRestrictions( 2144 DpmTestUtils.newRestrictions(), 2145 dpms.getProfileOwnerAdminLocked(CALLER_USER_HANDLE).ensureUserRestrictions() 2146 ); 2147 2148 dpm.addUserRestriction(admin1, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES); 2149 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 2150 eq(CALLER_USER_HANDLE), 2151 MockUtils.checkUserRestrictions(), 2152 MockUtils.checkUserRestrictions(CALLER_USER_HANDLE, 2153 UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES), 2154 eq(false)); 2155 2156 dpm.addUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS); 2157 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 2158 eq(CALLER_USER_HANDLE), 2159 MockUtils.checkUserRestrictions(), 2160 MockUtils.checkUserRestrictions(CALLER_USER_HANDLE, 2161 UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, 2162 UserManager.DISALLOW_OUTGOING_CALLS), 2163 eq(false)); 2164 2165 DpmTestUtils.assertRestrictions( 2166 DpmTestUtils.newRestrictions( 2167 UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, 2168 UserManager.DISALLOW_OUTGOING_CALLS 2169 ), 2170 dpms.getProfileOwnerAdminLocked(CALLER_USER_HANDLE) 2171 .ensureUserRestrictions() 2172 ); 2173 DpmTestUtils.assertRestrictions( 2174 DpmTestUtils.newRestrictions( 2175 UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, 2176 UserManager.DISALLOW_OUTGOING_CALLS 2177 ), 2178 dpm.getUserRestrictions(admin1) 2179 ); 2180 2181 dpm.clearUserRestriction(admin1, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES); 2182 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 2183 eq(CALLER_USER_HANDLE), 2184 MockUtils.checkUserRestrictions(), 2185 MockUtils.checkUserRestrictions(CALLER_USER_HANDLE, 2186 UserManager.DISALLOW_OUTGOING_CALLS), 2187 eq(false)); 2188 2189 DpmTestUtils.assertRestrictions( 2190 DpmTestUtils.newRestrictions( 2191 UserManager.DISALLOW_OUTGOING_CALLS 2192 ), 2193 dpms.getProfileOwnerAdminLocked(CALLER_USER_HANDLE) 2194 .ensureUserRestrictions() 2195 ); 2196 DpmTestUtils.assertRestrictions( 2197 DpmTestUtils.newRestrictions( 2198 UserManager.DISALLOW_OUTGOING_CALLS 2199 ), 2200 dpm.getUserRestrictions(admin1) 2201 ); 2202 2203 dpm.clearUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS); 2204 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 2205 eq(CALLER_USER_HANDLE), 2206 MockUtils.checkUserRestrictions(), 2207 MockUtils.checkUserRestrictions(CALLER_USER_HANDLE), eq(false)); 2208 2209 DpmTestUtils.assertRestrictions( 2210 DpmTestUtils.newRestrictions(), 2211 dpms.getProfileOwnerAdminLocked(CALLER_USER_HANDLE) 2212 .ensureUserRestrictions() 2213 ); 2214 DpmTestUtils.assertRestrictions( 2215 DpmTestUtils.newRestrictions(), 2216 dpm.getUserRestrictions(admin1) 2217 ); 2218 2219 // DISALLOW_ADJUST_VOLUME and DISALLOW_UNMUTE_MICROPHONE can be set by PO too, even 2220 // though when DO sets them they'll be applied globally. 2221 dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADJUST_VOLUME); 2222 2223 dpm.addUserRestriction(admin1, UserManager.DISALLOW_UNMUTE_MICROPHONE); 2224 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 2225 eq(CALLER_USER_HANDLE), 2226 MockUtils.checkUserRestrictions(), 2227 MockUtils.checkUserRestrictions(CALLER_USER_HANDLE, 2228 UserManager.DISALLOW_ADJUST_VOLUME, 2229 UserManager.DISALLOW_UNMUTE_MICROPHONE), 2230 eq(false)); 2231 2232 dpm.setCameraDisabled(admin1, true); 2233 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 2234 eq(CALLER_USER_HANDLE), 2235 MockUtils.checkUserRestrictions(), 2236 MockUtils.checkUserRestrictions(CALLER_USER_HANDLE, 2237 UserManager.DISALLOW_ADJUST_VOLUME, 2238 UserManager.DISALLOW_UNMUTE_MICROPHONE, 2239 UserManager.DISALLOW_CAMERA), 2240 eq(false)); 2241 reset(getServices().userManagerInternal); 2242 2243 // TODO Make sure restrictions are written to the file. 2244 } 2245 2246 private static final Set<String> PROFILE_OWNER_ORGANIZATION_OWNED_GLOBAL_RESTRICTIONS = 2247 Sets.newSet( 2248 UserManager.DISALLOW_AIRPLANE_MODE, 2249 UserManager.DISALLOW_CONFIG_DATE_TIME, 2250 UserManager.DISALLOW_CONFIG_PRIVATE_DNS 2251 ); 2252 2253 private static final Set<String> PROFILE_OWNER_ORGANIZATION_OWNED_LOCAL_RESTRICTIONS = 2254 Sets.newSet( 2255 UserManager.DISALLOW_CONFIG_BLUETOOTH, 2256 UserManager.DISALLOW_CONFIG_LOCATION, 2257 UserManager.DISALLOW_CONFIG_WIFI, 2258 UserManager.DISALLOW_CONTENT_CAPTURE, 2259 UserManager.DISALLOW_CONTENT_SUGGESTIONS, 2260 UserManager.DISALLOW_DEBUGGING_FEATURES, 2261 UserManager.DISALLOW_SHARE_LOCATION, 2262 UserManager.DISALLOW_OUTGOING_CALLS, 2263 UserManager.DISALLOW_BLUETOOTH_SHARING, 2264 UserManager.DISALLOW_CONFIG_CELL_BROADCASTS, 2265 UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS, 2266 UserManager.DISALLOW_CONFIG_TETHERING, 2267 UserManager.DISALLOW_DATA_ROAMING, 2268 UserManager.DISALLOW_SAFE_BOOT, 2269 UserManager.DISALLOW_SMS, 2270 UserManager.DISALLOW_USB_FILE_TRANSFER, 2271 UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA, 2272 UserManager.DISALLOW_UNMUTE_MICROPHONE 2273 ); 2274 2275 @Test testSetUserRestriction_asPoOfOrgOwnedDevice()2276 public void testSetUserRestriction_asPoOfOrgOwnedDevice() throws Exception { 2277 final int MANAGED_PROFILE_ADMIN_UID = 2278 UserHandle.getUid(CALLER_USER_HANDLE, DpmMockContext.SYSTEM_UID); 2279 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 2280 2281 addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1); 2282 configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE); 2283 2284 when(getServices().userManager.getProfileParent(CALLER_USER_HANDLE)) 2285 .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0)); 2286 2287 for (String restriction : PROFILE_OWNER_ORGANIZATION_OWNED_GLOBAL_RESTRICTIONS) { 2288 addAndRemoveGlobalUserRestrictionOnParentDpm(restriction); 2289 } 2290 for (String restriction : PROFILE_OWNER_ORGANIZATION_OWNED_LOCAL_RESTRICTIONS) { 2291 addAndRemoveLocalUserRestrictionOnParentDpm(restriction); 2292 } 2293 2294 parentDpm.setCameraDisabled(admin1, true); 2295 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 2296 eq(CALLER_USER_HANDLE), 2297 MockUtils.checkUserRestrictions(), 2298 MockUtils.checkUserRestrictions(UserHandle.USER_SYSTEM, 2299 UserManager.DISALLOW_CAMERA), 2300 eq(false)); 2301 DpmTestUtils.assertRestrictions( 2302 DpmTestUtils.newRestrictions(UserManager.DISALLOW_CAMERA), 2303 dpms.getProfileOwnerAdminLocked(CALLER_USER_HANDLE) 2304 .getParentActiveAdmin() 2305 .getEffectiveRestrictions() 2306 ); 2307 2308 parentDpm.setCameraDisabled(admin1, false); 2309 DpmTestUtils.assertRestrictions( 2310 DpmTestUtils.newRestrictions(), 2311 dpms.getProfileOwnerAdminLocked(CALLER_USER_HANDLE) 2312 .getParentActiveAdmin() 2313 .getEffectiveRestrictions() 2314 ); 2315 reset(getServices().userManagerInternal); 2316 } 2317 addAndRemoveGlobalUserRestrictionOnParentDpm(String restriction)2318 private void addAndRemoveGlobalUserRestrictionOnParentDpm(String restriction) { 2319 parentDpm.addUserRestriction(admin1, restriction); 2320 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 2321 eq(CALLER_USER_HANDLE), 2322 MockUtils.checkUserRestrictions(restriction), 2323 MockUtils.checkUserRestrictions(CALLER_USER_HANDLE), 2324 eq(false)); 2325 parentDpm.clearUserRestriction(admin1, restriction); 2326 DpmTestUtils.assertRestrictions( 2327 DpmTestUtils.newRestrictions(), 2328 dpms.getProfileOwnerAdminLocked(CALLER_USER_HANDLE) 2329 .getParentActiveAdmin() 2330 .getEffectiveRestrictions() 2331 ); 2332 } 2333 addAndRemoveLocalUserRestrictionOnParentDpm(String restriction)2334 private void addAndRemoveLocalUserRestrictionOnParentDpm(String restriction) { 2335 parentDpm.addUserRestriction(admin1, restriction); 2336 verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions( 2337 eq(CALLER_USER_HANDLE), 2338 MockUtils.checkUserRestrictions(), 2339 MockUtils.checkUserRestrictions(UserHandle.USER_SYSTEM, restriction), 2340 eq(false)); 2341 parentDpm.clearUserRestriction(admin1, restriction); 2342 DpmTestUtils.assertRestrictions( 2343 DpmTestUtils.newRestrictions(), 2344 dpms.getProfileOwnerAdminLocked(CALLER_USER_HANDLE) 2345 .getParentActiveAdmin() 2346 .getEffectiveRestrictions() 2347 ); 2348 } 2349 2350 @Test testNoDefaultEnabledUserRestrictions()2351 public void testNoDefaultEnabledUserRestrictions() throws Exception { 2352 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 2353 mContext.callerPermissions.add(permission.MANAGE_USERS); 2354 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2355 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); 2356 2357 // First, set DO. 2358 2359 // Call from a process on the system user. 2360 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 2361 2362 // Make sure admin1 is installed on system user. 2363 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 2364 2365 dpm.setActiveAdmin(admin1, /* replace =*/ false, UserHandle.USER_SYSTEM); 2366 assertThat(dpm.setDeviceOwner(admin1, "owner-name", 2367 UserHandle.USER_SYSTEM)).isTrue(); 2368 2369 assertNoDeviceOwnerRestrictions(); 2370 2371 reset(getServices().userManagerInternal); 2372 2373 // Ensure the DISALLOW_REMOVE_MANAGED_PROFILES restriction doesn't show up as a 2374 // restriction to the device owner. 2375 dpm.addUserRestriction(admin1, UserManager.DISALLOW_REMOVE_MANAGED_PROFILE); 2376 assertNoDeviceOwnerRestrictions(); 2377 } 2378 assertNoDeviceOwnerRestrictions()2379 private void assertNoDeviceOwnerRestrictions() { 2380 DpmTestUtils.assertRestrictions( 2381 DpmTestUtils.newRestrictions(), 2382 getDeviceOwner().getEffectiveRestrictions() 2383 ); 2384 } 2385 2386 @Test testSetFactoryResetProtectionPolicyWithDO()2387 public void testSetFactoryResetProtectionPolicyWithDO() throws Exception { 2388 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 2389 setupDeviceOwner(); 2390 2391 when(getServices().persistentDataBlockManagerInternal.getAllowedUid()).thenReturn( 2392 DpmMockContext.CALLER_UID); 2393 2394 FactoryResetProtectionPolicy policy = new FactoryResetProtectionPolicy.Builder() 2395 .setFactoryResetProtectionAccounts(new ArrayList<>()) 2396 .setFactoryResetProtectionEnabled(false) 2397 .build(); 2398 dpm.setFactoryResetProtectionPolicy(admin1, policy); 2399 2400 FactoryResetProtectionPolicy result = dpm.getFactoryResetProtectionPolicy(admin1); 2401 assertThat(result).isEqualTo(policy); 2402 assertPoliciesAreEqual(policy, result); 2403 2404 verify(mContext.spiedContext).sendBroadcastAsUser( 2405 MockUtils.checkIntentAction( 2406 DevicePolicyManager.ACTION_RESET_PROTECTION_POLICY_CHANGED), 2407 MockUtils.checkUserHandle(CALLER_USER_HANDLE), 2408 eq(android.Manifest.permission.MANAGE_FACTORY_RESET_PROTECTION)); 2409 } 2410 2411 @Test testSetFactoryResetProtectionPolicyFailWithPO()2412 public void testSetFactoryResetProtectionPolicyFailWithPO() throws Exception { 2413 setupProfileOwner(); 2414 2415 FactoryResetProtectionPolicy policy = new FactoryResetProtectionPolicy.Builder() 2416 .setFactoryResetProtectionEnabled(false) 2417 .build(); 2418 2419 assertExpectException(SecurityException.class, null, 2420 () -> dpm.setFactoryResetProtectionPolicy(admin1, policy)); 2421 } 2422 2423 @Test testSetFactoryResetProtectionPolicyWithPOOfOrganizationOwnedDevice()2424 public void testSetFactoryResetProtectionPolicyWithPOOfOrganizationOwnedDevice() 2425 throws Exception { 2426 setupProfileOwner(); 2427 configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE); 2428 2429 when(getServices().persistentDataBlockManagerInternal.getAllowedUid()).thenReturn( 2430 DpmMockContext.CALLER_UID); 2431 2432 List<String> accounts = new ArrayList<>(); 2433 accounts.add("Account 1"); 2434 accounts.add("Account 2"); 2435 2436 FactoryResetProtectionPolicy policy = new FactoryResetProtectionPolicy.Builder() 2437 .setFactoryResetProtectionAccounts(accounts) 2438 .build(); 2439 2440 dpm.setFactoryResetProtectionPolicy(admin1, policy); 2441 2442 FactoryResetProtectionPolicy result = dpm.getFactoryResetProtectionPolicy(admin1); 2443 assertThat(result).isEqualTo(policy); 2444 assertPoliciesAreEqual(policy, result); 2445 2446 verify(mContext.spiedContext, times(2)).sendBroadcastAsUser( 2447 MockUtils.checkIntentAction( 2448 DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED), 2449 MockUtils.checkUserHandle(CALLER_USER_HANDLE)); 2450 verify(mContext.spiedContext).sendBroadcastAsUser( 2451 MockUtils.checkIntentAction( 2452 DevicePolicyManager.ACTION_PROFILE_OWNER_CHANGED), 2453 MockUtils.checkUserHandle(CALLER_USER_HANDLE)); 2454 verify(mContext.spiedContext).sendBroadcastAsUser( 2455 MockUtils.checkIntentAction( 2456 DevicePolicyManager.ACTION_RESET_PROTECTION_POLICY_CHANGED), 2457 MockUtils.checkUserHandle(CALLER_USER_HANDLE), 2458 eq(android.Manifest.permission.MANAGE_FACTORY_RESET_PROTECTION)); 2459 } 2460 2461 @Test testGetFactoryResetProtectionPolicyWithFrpManagementAgent()2462 public void testGetFactoryResetProtectionPolicyWithFrpManagementAgent() 2463 throws Exception { 2464 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 2465 setupDeviceOwner(); 2466 when(getServices().persistentDataBlockManagerInternal.getAllowedUid()).thenReturn( 2467 DpmMockContext.CALLER_UID); 2468 2469 FactoryResetProtectionPolicy policy = new FactoryResetProtectionPolicy.Builder() 2470 .setFactoryResetProtectionAccounts(new ArrayList<>()) 2471 .setFactoryResetProtectionEnabled(false) 2472 .build(); 2473 2474 dpm.setFactoryResetProtectionPolicy(admin1, policy); 2475 2476 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 2477 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 2478 dpm.setActiveAdmin(admin1, /*replace=*/ false); 2479 FactoryResetProtectionPolicy result = dpm.getFactoryResetProtectionPolicy(null); 2480 assertThat(result).isEqualTo(policy); 2481 assertPoliciesAreEqual(policy, result); 2482 2483 verify(mContext.spiedContext).sendBroadcastAsUser( 2484 MockUtils.checkIntentAction( 2485 DevicePolicyManager.ACTION_RESET_PROTECTION_POLICY_CHANGED), 2486 MockUtils.checkUserHandle(CALLER_USER_HANDLE), 2487 eq(android.Manifest.permission.MANAGE_FACTORY_RESET_PROTECTION)); 2488 } 2489 assertPoliciesAreEqual(FactoryResetProtectionPolicy expectedPolicy, FactoryResetProtectionPolicy actualPolicy)2490 private void assertPoliciesAreEqual(FactoryResetProtectionPolicy expectedPolicy, 2491 FactoryResetProtectionPolicy actualPolicy) { 2492 assertThat(actualPolicy.isFactoryResetProtectionEnabled()).isEqualTo( 2493 expectedPolicy.isFactoryResetProtectionEnabled()); 2494 assertAccountsAreEqual(expectedPolicy.getFactoryResetProtectionAccounts(), 2495 actualPolicy.getFactoryResetProtectionAccounts()); 2496 } 2497 assertAccountsAreEqual(List<String> expectedAccounts, List<String> actualAccounts)2498 private void assertAccountsAreEqual(List<String> expectedAccounts, 2499 List<String> actualAccounts) { 2500 assertThat(actualAccounts).containsExactlyElementsIn(expectedAccounts); 2501 } 2502 2503 @Test testSetPermittedInputMethodsWithPOOfOrganizationOwnedDevice()2504 public void testSetPermittedInputMethodsWithPOOfOrganizationOwnedDevice() 2505 throws Exception { 2506 String packageName = "com.google.pkg.one"; 2507 setupProfileOwner(); 2508 configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE); 2509 2510 // Allow all input methods 2511 parentDpm.setPermittedInputMethods(admin1, null); 2512 2513 assertThat(parentDpm.getPermittedInputMethods(admin1)).isNull(); 2514 2515 // Allow only system input methods 2516 parentDpm.setPermittedInputMethods(admin1, new ArrayList<>()); 2517 2518 assertThat(parentDpm.getPermittedInputMethods(admin1)).isEmpty(); 2519 2520 // Don't allow specific third party input methods 2521 final List<String> inputMethods = Collections.singletonList(packageName); 2522 2523 assertExpectException(IllegalArgumentException.class, /* messageRegex= */ "Permitted " 2524 + "input methods must allow all input methods or only system input methods " 2525 + "when called on the parent instance of an organization-owned device", 2526 () -> parentDpm.setPermittedInputMethods(admin1, inputMethods)); 2527 } 2528 2529 @Test testGetProxyParameters()2530 public void testGetProxyParameters() throws Exception { 2531 assertThat(dpm.getProxyParameters(inetAddrProxy("192.0.2.1", 1234), emptyList())) 2532 .isEqualTo(new Pair<>("192.0.2.1:1234", "")); 2533 assertThat(dpm.getProxyParameters(inetAddrProxy("192.0.2.1", 1234), 2534 listOf("one.example.com ", " two.example.com "))) 2535 .isEqualTo(new Pair<>("192.0.2.1:1234", "one.example.com,two.example.com")); 2536 assertThat(dpm.getProxyParameters(hostnameProxy("proxy.example.com", 1234), emptyList())) 2537 .isEqualTo(new Pair<>("proxy.example.com:1234", "")); 2538 assertThat(dpm.getProxyParameters(hostnameProxy("proxy.example.com", 1234), 2539 listOf("excluded.example.com"))) 2540 .isEqualTo(new Pair<>("proxy.example.com:1234", "excluded.example.com")); 2541 2542 assertThrows(IllegalArgumentException.class, () -> dpm.getProxyParameters( 2543 inetAddrProxy("192.0.2.1", 0), emptyList())); 2544 assertThrows(IllegalArgumentException.class, () -> dpm.getProxyParameters( 2545 hostnameProxy("", 1234), emptyList())); 2546 assertThrows(IllegalArgumentException.class, () -> dpm.getProxyParameters( 2547 hostnameProxy("", 0), emptyList())); 2548 assertThrows(IllegalArgumentException.class, () -> dpm.getProxyParameters( 2549 hostnameProxy("invalid! hostname", 1234), emptyList())); 2550 assertThrows(IllegalArgumentException.class, () -> dpm.getProxyParameters( 2551 hostnameProxy("proxy.example.com", 1234), listOf("invalid exclusion"))); 2552 assertThrows(IllegalArgumentException.class, () -> dpm.getProxyParameters( 2553 hostnameProxy("proxy.example.com", -1), emptyList())); 2554 assertThrows(IllegalArgumentException.class, () -> dpm.getProxyParameters( 2555 hostnameProxy("proxy.example.com", 0xFFFF + 1), emptyList())); 2556 } 2557 inetAddrProxy(String inetAddr, int port)2558 private static Proxy inetAddrProxy(String inetAddr, int port) { 2559 return new Proxy( 2560 Proxy.Type.HTTP, new InetSocketAddress(parseNumericAddress(inetAddr), port)); 2561 } 2562 hostnameProxy(String hostname, int port)2563 private static Proxy hostnameProxy(String hostname, int port) { 2564 return new Proxy( 2565 Proxy.Type.HTTP, InetSocketAddress.createUnresolved(hostname, port)); 2566 } 2567 listOf(String... args)2568 private static List<String> listOf(String... args) { 2569 return Arrays.asList(args); 2570 } 2571 2572 @Test testSetKeyguardDisabledFeaturesWithDO()2573 public void testSetKeyguardDisabledFeaturesWithDO() throws Exception { 2574 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 2575 setupDeviceOwner(); 2576 2577 dpm.setKeyguardDisabledFeatures(admin1, DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA); 2578 2579 assertThat(dpm.getKeyguardDisabledFeatures(admin1)).isEqualTo( 2580 DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA); 2581 } 2582 2583 @Test testSetKeyguardDisabledFeaturesWithPO()2584 public void testSetKeyguardDisabledFeaturesWithPO() throws Exception { 2585 setupProfileOwner(); 2586 2587 dpm.setKeyguardDisabledFeatures(admin1, DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT); 2588 2589 assertThat(dpm.getKeyguardDisabledFeatures(admin1)).isEqualTo( 2590 DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT); 2591 } 2592 2593 @Test testSetKeyguardDisabledFeaturesWithPOOfOrganizationOwnedDevice()2594 public void testSetKeyguardDisabledFeaturesWithPOOfOrganizationOwnedDevice() 2595 throws Exception { 2596 final int MANAGED_PROFILE_USER_ID = CALLER_USER_HANDLE; 2597 final int MANAGED_PROFILE_ADMIN_UID = 2598 UserHandle.getUid(MANAGED_PROFILE_USER_ID, DpmMockContext.SYSTEM_UID); 2599 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 2600 2601 addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1); 2602 configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE); 2603 2604 parentDpm.setKeyguardDisabledFeatures(admin1, 2605 DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA); 2606 2607 assertThat(parentDpm.getKeyguardDisabledFeatures(admin1)).isEqualTo( 2608 DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA); 2609 } 2610 2611 @Test testSetApplicationHiddenWithDO()2612 public void testSetApplicationHiddenWithDO() throws Exception { 2613 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 2614 setupDeviceOwner(); 2615 mContext.packageName = admin1.getPackageName(); 2616 setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid); 2617 mockEmptyPolicyExemptApps(); 2618 2619 String packageName = "com.google.android.test"; 2620 2621 dpm.setApplicationHidden(admin1, packageName, true); 2622 verify(getServices().ipackageManager).setApplicationHiddenSettingAsUser(packageName, 2623 true, UserHandle.USER_SYSTEM); 2624 2625 dpm.setApplicationHidden(admin1, packageName, false); 2626 verify(getServices().ipackageManager).setApplicationHiddenSettingAsUser(packageName, 2627 false, UserHandle.USER_SYSTEM); 2628 2629 verify(getServices().ipackageManager, never()).getPackageInfo(packageName, 2630 PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM); 2631 verify(getServices().ipackageManager, never()).getPackageInfo(packageName, 2632 PackageManager.MATCH_UNINSTALLED_PACKAGES | PackageManager.MATCH_SYSTEM_ONLY, 2633 UserHandle.USER_SYSTEM); 2634 } 2635 2636 @Test testSetApplicationHiddenWithPOOfOrganizationOwnedDevice()2637 public void testSetApplicationHiddenWithPOOfOrganizationOwnedDevice() throws Exception { 2638 final int MANAGED_PROFILE_USER_ID = CALLER_USER_HANDLE; 2639 final int MANAGED_PROFILE_ADMIN_UID = 2640 UserHandle.getUid(MANAGED_PROFILE_USER_ID, DpmMockContext.SYSTEM_UID); 2641 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 2642 2643 addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1); 2644 configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE); 2645 mContext.packageName = admin1.getPackageName(); 2646 setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid); 2647 mockEmptyPolicyExemptApps(); 2648 2649 String packageName = "com.google.android.test"; 2650 2651 ApplicationInfo applicationInfo = new ApplicationInfo(); 2652 applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM; 2653 when(getServices().userManager.getProfileParent(MANAGED_PROFILE_USER_ID)) 2654 .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0)); 2655 when(getServices().ipackageManager.getApplicationInfo(packageName, 2656 PackageManager.MATCH_UNINSTALLED_PACKAGES, UserHandle.USER_SYSTEM)).thenReturn( 2657 applicationInfo); 2658 2659 parentDpm.setApplicationHidden(admin1, packageName, true); 2660 verify(getServices().ipackageManager).setApplicationHiddenSettingAsUser(packageName, 2661 true, UserHandle.USER_SYSTEM); 2662 2663 parentDpm.setApplicationHidden(admin1, packageName, false); 2664 verify(getServices().ipackageManager).setApplicationHiddenSettingAsUser(packageName, 2665 false, UserHandle.USER_SYSTEM); 2666 } 2667 2668 @Test testGetMacAddress()2669 public void testGetMacAddress() throws Exception { 2670 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 2671 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2672 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); 2673 2674 // In this test, change the caller user to "system". 2675 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 2676 2677 // Make sure admin1 is installed on system user. 2678 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 2679 2680 // Test 1. Caller doesn't have DO or DA. 2681 assertExpectException(SecurityException.class, /* messageRegex= */ 2682 "does not exist or is not owned by uid", () -> dpm.getWifiMacAddress(admin1)); 2683 2684 // DO needs to be an DA. 2685 dpm.setActiveAdmin(admin1, /* replace =*/ false); 2686 assertThat(dpm.isAdminActive(admin1)).isTrue(); 2687 2688 // Test 2. Caller has DA, but not DO. 2689 assertExpectException(SecurityException.class, 2690 /* messageRegex= */ INVALID_CALLING_IDENTITY_MSG, 2691 () -> dpm.getWifiMacAddress(admin1)); 2692 2693 // Test 3. Caller has PO, but not DO. 2694 assertThat(dpm.setProfileOwner(admin1, null, UserHandle.USER_SYSTEM)).isTrue(); 2695 assertExpectException(SecurityException.class, 2696 /* messageRegex= */ INVALID_CALLING_IDENTITY_MSG, 2697 () -> dpm.getWifiMacAddress(admin1)); 2698 2699 // Remove PO. 2700 dpm.clearProfileOwner(admin1); 2701 dpm.setActiveAdmin(admin1, false); 2702 // Test 4, Caller is DO now. 2703 assertThat(dpm.setDeviceOwner(admin1, null, UserHandle.USER_SYSTEM)).isTrue(); 2704 2705 // 4-1. But WifiManager is not ready. 2706 assertThat(dpm.getWifiMacAddress(admin1)).isNull(); 2707 2708 // 4-2. When WifiManager returns an empty array, dpm should also output null. 2709 when(getServices().wifiManager.getFactoryMacAddresses()).thenReturn(new String[0]); 2710 assertThat(dpm.getWifiMacAddress(admin1)).isNull(); 2711 2712 // 4-3. With a real MAC address. 2713 final String[] macAddresses = new String[]{"11:22:33:44:55:66"}; 2714 when(getServices().wifiManager.getFactoryMacAddresses()).thenReturn(macAddresses); 2715 assertThat(dpm.getWifiMacAddress(admin1)).isEqualTo("11:22:33:44:55:66"); 2716 } 2717 2718 @Test testGetMacAddressByOrgOwnedPO()2719 public void testGetMacAddressByOrgOwnedPO() throws Exception { 2720 setupProfileOwner(); 2721 configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE); 2722 2723 final String[] macAddresses = new String[]{"11:22:33:44:55:66"}; 2724 when(getServices().wifiManager.getFactoryMacAddresses()).thenReturn(macAddresses); 2725 assertThat(dpm.getWifiMacAddress(admin1)).isEqualTo("11:22:33:44:55:66"); 2726 } 2727 2728 @Test testReboot()2729 public void testReboot() throws Exception { 2730 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 2731 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 2732 2733 // In this test, change the caller user to "system". 2734 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 2735 2736 // Make sure admin1 is installed on system user. 2737 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 2738 2739 // Set admin1 as DA. 2740 dpm.setActiveAdmin(admin1, false); 2741 assertThat(dpm.isAdminActive(admin1)).isTrue(); 2742 assertExpectException(SecurityException.class, /* messageRegex= */ 2743 INVALID_CALLING_IDENTITY_MSG, () -> dpm.reboot(admin1)); 2744 2745 // Set admin1 as PO. 2746 assertThat(dpm.setProfileOwner(admin1, null, UserHandle.USER_SYSTEM)).isTrue(); 2747 assertExpectException(SecurityException.class, /* messageRegex= */ 2748 INVALID_CALLING_IDENTITY_MSG, () -> dpm.reboot(admin1)); 2749 2750 // Remove PO and add DO. 2751 dpm.clearProfileOwner(admin1); 2752 dpm.setActiveAdmin(admin1, false); 2753 assertThat(dpm.setDeviceOwner(admin1, null, UserHandle.USER_SYSTEM)).isTrue(); 2754 2755 // admin1 is DO. 2756 // Set current call state of device to ringing. 2757 when(getServices().telephonyManager.getCallState()) 2758 .thenReturn(TelephonyManager.CALL_STATE_RINGING); 2759 assertExpectException(IllegalStateException.class, /* messageRegex= */ ONGOING_CALL_MSG, 2760 () -> dpm.reboot(admin1)); 2761 2762 // Set current call state of device to dialing/active. 2763 when(getServices().telephonyManager.getCallState()) 2764 .thenReturn(TelephonyManager.CALL_STATE_OFFHOOK); 2765 assertExpectException(IllegalStateException.class, /* messageRegex= */ ONGOING_CALL_MSG, 2766 () -> dpm.reboot(admin1)); 2767 2768 // Set current call state of device to idle. 2769 when(getServices().telephonyManager.getCallState()) 2770 .thenReturn(TelephonyManager.CALL_STATE_IDLE); 2771 dpm.reboot(admin1); 2772 } 2773 2774 @Test testSetGetSupportText()2775 public void testSetGetSupportText() { 2776 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 2777 dpm.setActiveAdmin(admin1, true); 2778 dpm.setActiveAdmin(admin2, true); 2779 mContext.callerPermissions.remove(permission.MANAGE_DEVICE_ADMINS); 2780 2781 // Null default support messages. 2782 { 2783 assertThat(dpm.getLongSupportMessage(admin1)).isNull(); 2784 assertThat(dpm.getShortSupportMessage(admin1)).isNull(); 2785 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 2786 assertThat(dpm.getShortSupportMessageForUser(admin1, CALLER_USER_HANDLE)).isNull(); 2787 assertThat(dpm.getLongSupportMessageForUser(admin1, CALLER_USER_HANDLE)).isNull(); 2788 mMockContext.binder.callingUid = DpmMockContext.CALLER_UID; 2789 } 2790 2791 // Only system can call the per user versions. 2792 { 2793 assertExpectException(SecurityException.class, /* messageRegex= */ "message for user", 2794 () -> dpm.getShortSupportMessageForUser(admin1, CALLER_USER_HANDLE)); 2795 assertExpectException(SecurityException.class, /* messageRegex= */ "message for user", 2796 () -> dpm.getLongSupportMessageForUser(admin1, CALLER_USER_HANDLE)); 2797 } 2798 2799 // Can't set message for admin in another uid. 2800 { 2801 mContext.binder.callingUid = DpmMockContext.CALLER_UID + 1; 2802 assertExpectException(SecurityException.class, 2803 /* messageRegex= */ "is not owned by uid", 2804 () -> dpm.setShortSupportMessage(admin1, "Some text")); 2805 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 2806 } 2807 2808 // Set/Get short returns what it sets and other admins text isn't changed. 2809 { 2810 final String supportText = "Some text to test with."; 2811 dpm.setShortSupportMessage(admin1, supportText); 2812 assertThat(dpm.getShortSupportMessage(admin1)).isEqualTo(supportText); 2813 assertThat(dpm.getLongSupportMessage(admin1)).isNull(); 2814 assertThat(dpm.getShortSupportMessage(admin2)).isNull(); 2815 2816 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 2817 assertThat(dpm.getShortSupportMessageForUser(admin1, 2818 CALLER_USER_HANDLE)).isEqualTo(supportText); 2819 assertThat(dpm.getShortSupportMessageForUser(admin2, CALLER_USER_HANDLE)).isNull(); 2820 assertThat(dpm.getLongSupportMessageForUser(admin1, CALLER_USER_HANDLE)).isNull(); 2821 mMockContext.binder.callingUid = DpmMockContext.CALLER_UID; 2822 2823 dpm.setShortSupportMessage(admin1, null); 2824 assertThat(dpm.getShortSupportMessage(admin1)).isNull(); 2825 } 2826 2827 // Set/Get long returns what it sets and other admins text isn't changed. 2828 { 2829 final String supportText = "Some text to test with.\nWith more text."; 2830 dpm.setLongSupportMessage(admin1, supportText); 2831 assertThat(dpm.getLongSupportMessage(admin1)).isEqualTo(supportText); 2832 assertThat(dpm.getShortSupportMessage(admin1)).isNull(); 2833 assertThat(dpm.getLongSupportMessage(admin2)).isNull(); 2834 2835 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 2836 assertThat(dpm.getLongSupportMessageForUser(admin1, 2837 CALLER_USER_HANDLE)).isEqualTo(supportText); 2838 assertThat(dpm.getLongSupportMessageForUser(admin2, CALLER_USER_HANDLE)).isNull(); 2839 assertThat(dpm.getShortSupportMessageForUser(admin1, CALLER_USER_HANDLE)).isNull(); 2840 mMockContext.binder.callingUid = DpmMockContext.CALLER_UID; 2841 2842 dpm.setLongSupportMessage(admin1, null); 2843 assertThat(dpm.getLongSupportMessage(admin1)).isNull(); 2844 } 2845 } 2846 2847 @Test testSetGetMeteredDataDisabledPackages()2848 public void testSetGetMeteredDataDisabledPackages() throws Exception { 2849 setAsProfileOwner(admin1); 2850 2851 assertThat(dpm.getMeteredDataDisabledPackages(admin1)).isEmpty(); 2852 2853 // Setup 2854 final ArrayList<String> pkgsToRestrict = new ArrayList<>(); 2855 final String package1 = "com.example.one"; 2856 final String package2 = "com.example.two"; 2857 pkgsToRestrict.add(package1); 2858 pkgsToRestrict.add(package2); 2859 setupPackageInPackageManager(package1, CALLER_USER_HANDLE, 123, 0); 2860 setupPackageInPackageManager(package2, CALLER_USER_HANDLE, 456, 0); 2861 List<String> excludedPkgs = dpm.setMeteredDataDisabledPackages(admin1, pkgsToRestrict); 2862 2863 // Verify 2864 assertThat(excludedPkgs).isEmpty(); 2865 assertThat(dpm.getMeteredDataDisabledPackages(admin1)).isEqualTo(pkgsToRestrict); 2866 verify(getServices().networkPolicyManagerInternal).setMeteredRestrictedPackages( 2867 MockUtils.checkApps(pkgsToRestrict.toArray(new String[0])), 2868 eq(CALLER_USER_HANDLE)); 2869 2870 // Setup 2871 pkgsToRestrict.remove(package1); 2872 excludedPkgs = dpm.setMeteredDataDisabledPackages(admin1, pkgsToRestrict); 2873 2874 // Verify 2875 assertThat(excludedPkgs).isEmpty(); 2876 assertThat(dpm.getMeteredDataDisabledPackages(admin1)).isEqualTo(pkgsToRestrict); 2877 verify(getServices().networkPolicyManagerInternal).setMeteredRestrictedPackages( 2878 MockUtils.checkApps(pkgsToRestrict.toArray(new String[0])), 2879 eq(CALLER_USER_HANDLE)); 2880 } 2881 2882 @Test testSetGetMeteredDataDisabledPackages_deviceAdmin()2883 public void testSetGetMeteredDataDisabledPackages_deviceAdmin() { 2884 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 2885 dpm.setActiveAdmin(admin1, true); 2886 assertThat(dpm.isAdminActive(admin1)).isTrue(); 2887 mContext.callerPermissions.remove(permission.MANAGE_DEVICE_ADMINS); 2888 2889 assertExpectException(SecurityException.class, /* messageRegex= */ NOT_PROFILE_OWNER_MSG, 2890 () -> dpm.setMeteredDataDisabledPackages(admin1, new ArrayList<>())); 2891 assertExpectException(SecurityException.class, /* messageRegex= */ NOT_PROFILE_OWNER_MSG, 2892 () -> dpm.getMeteredDataDisabledPackages(admin1)); 2893 } 2894 2895 @Test testIsMeteredDataDisabledForUserPackage()2896 public void testIsMeteredDataDisabledForUserPackage() throws Exception { 2897 setAsProfileOwner(admin1); 2898 2899 // Setup 2900 final ArrayList<String> pkgsToRestrict = new ArrayList<>(); 2901 final String package1 = "com.example.one"; 2902 final String package2 = "com.example.two"; 2903 final String package3 = "com.example.three"; 2904 pkgsToRestrict.add(package1); 2905 pkgsToRestrict.add(package2); 2906 setupPackageInPackageManager(package1, CALLER_USER_HANDLE, 123, 0); 2907 setupPackageInPackageManager(package2, CALLER_USER_HANDLE, 456, 0); 2908 List<String> excludedPkgs = dpm.setMeteredDataDisabledPackages(admin1, pkgsToRestrict); 2909 2910 // Verify 2911 assertThat(excludedPkgs).isEmpty(); 2912 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 2913 assertWithMessage("%s should be restricted", package1) 2914 .that(dpm.isMeteredDataDisabledPackageForUser(admin1, package1, CALLER_USER_HANDLE)) 2915 .isTrue(); 2916 assertWithMessage("%s should be restricted", package2) 2917 .that(dpm.isMeteredDataDisabledPackageForUser(admin1, package2, CALLER_USER_HANDLE)) 2918 .isTrue(); 2919 assertWithMessage("%s should not be restricted", package3) 2920 .that(dpm.isMeteredDataDisabledPackageForUser(admin1, package3, CALLER_USER_HANDLE)) 2921 .isFalse(); 2922 } 2923 2924 @Test testIsMeteredDataDisabledForUserPackage_nonSystemUidCaller()2925 public void testIsMeteredDataDisabledForUserPackage_nonSystemUidCaller() throws Exception { 2926 setAsProfileOwner(admin1); 2927 assertExpectException(SecurityException.class, 2928 /* messageRegex= */ "Only the system can query restricted pkgs", 2929 () -> dpm.isMeteredDataDisabledPackageForUser( 2930 admin1, "com.example.one", CALLER_USER_HANDLE)); 2931 dpm.clearProfileOwner(admin1); 2932 2933 setDeviceOwner(); 2934 assertExpectException(SecurityException.class, 2935 /* messageRegex= */ "Only the system can query restricted pkgs", 2936 () -> dpm.isMeteredDataDisabledPackageForUser( 2937 admin1, "com.example.one", CALLER_USER_HANDLE)); 2938 clearDeviceOwner(); 2939 } 2940 2941 @Test testCreateAdminSupportIntent()2942 public void testCreateAdminSupportIntent() throws Exception { 2943 // Setup device owner. 2944 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 2945 setupDeviceOwner(); 2946 2947 // Nonexisting permission returns null 2948 Intent intent = dpm.createAdminSupportIntent("disallow_nothing"); 2949 assertThat(intent).isNull(); 2950 2951 // Existing permission that is not set returns null 2952 intent = dpm.createAdminSupportIntent(UserManager.DISALLOW_ADJUST_VOLUME); 2953 assertThat(intent).isNull(); 2954 2955 // Existing permission that is not set by device/profile owner returns null 2956 when(getServices().userManager.hasUserRestriction( 2957 eq(UserManager.DISALLOW_ADJUST_VOLUME), 2958 eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid)))) 2959 .thenReturn(true); 2960 intent = dpm.createAdminSupportIntent(UserManager.DISALLOW_ADJUST_VOLUME); 2961 assertThat(intent).isNull(); 2962 2963 // UM.getUserRestrictionSources() will return a list of size 1 with the caller resource. 2964 doAnswer((Answer<List<UserManager.EnforcingUser>>) invocation -> Collections.singletonList( 2965 new UserManager.EnforcingUser( 2966 UserHandle.USER_SYSTEM, 2967 UserManager.RESTRICTION_SOURCE_DEVICE_OWNER)) 2968 ).when(getServices().userManager).getUserRestrictionSources( 2969 eq(UserManager.DISALLOW_ADJUST_VOLUME), 2970 eq(UserHandle.of(UserHandle.USER_SYSTEM))); 2971 intent = dpm.createAdminSupportIntent(UserManager.DISALLOW_ADJUST_VOLUME); 2972 assertThat(intent).isNotNull(); 2973 assertThat(intent.getAction()).isEqualTo(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS); 2974 assertThat(intent.getIntExtra(Intent.EXTRA_USER_ID, -1)) 2975 .isEqualTo(UserHandle.getUserId(DpmMockContext.CALLER_SYSTEM_USER_UID)); 2976 assertThat(intent.getStringExtra(DevicePolicyManager.EXTRA_RESTRICTION)) 2977 .isEqualTo(UserManager.DISALLOW_ADJUST_VOLUME); 2978 2979 // Try with POLICY_DISABLE_CAMERA and POLICY_DISABLE_SCREEN_CAPTURE, which are not 2980 // user restrictions 2981 2982 // Camera is not disabled 2983 intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_CAMERA); 2984 assertThat(intent).isNull(); 2985 2986 // Camera is disabled 2987 dpm.setCameraDisabled(admin1, true); 2988 intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_CAMERA); 2989 assertThat(intent).isNotNull(); 2990 assertThat(intent.getStringExtra(DevicePolicyManager.EXTRA_RESTRICTION)) 2991 .isEqualTo(DevicePolicyManager.POLICY_DISABLE_CAMERA); 2992 2993 // Screen capture is not disabled 2994 intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE); 2995 assertThat(intent).isNull(); 2996 2997 // Screen capture is disabled 2998 dpm.setScreenCaptureDisabled(admin1, true); 2999 intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE); 3000 assertThat(intent).isNotNull(); 3001 assertThat(intent.getStringExtra(DevicePolicyManager.EXTRA_RESTRICTION)) 3002 .isEqualTo(DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE); 3003 3004 // Same checks for different user 3005 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 3006 // Camera should be disabled by device owner 3007 intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_CAMERA); 3008 assertThat(intent).isNotNull(); 3009 assertThat(intent.getStringExtra(DevicePolicyManager.EXTRA_RESTRICTION)) 3010 .isEqualTo(DevicePolicyManager.POLICY_DISABLE_CAMERA); 3011 assertThat(intent.getIntExtra(Intent.EXTRA_USER_ID, -1)) 3012 .isEqualTo(UserHandle.getUserId(DpmMockContext.CALLER_UID)); 3013 // ScreenCapture should not be disabled by device owner 3014 intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE); 3015 assertThat(intent).isNull(); 3016 } 3017 3018 /** 3019 * Test for: 3020 * {@link DevicePolicyManager#setAffiliationIds} 3021 * {@link DevicePolicyManager#getAffiliationIds} 3022 * {@link DevicePolicyManager#isAffiliatedUser} 3023 */ 3024 @Test testUserAffiliation()3025 public void testUserAffiliation() throws Exception { 3026 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 3027 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 3028 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL); 3029 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS); 3030 3031 // Check that the system user is unaffiliated. 3032 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3033 assertThat(dpm.isAffiliatedUser()).isFalse(); 3034 3035 // Set a device owner on the system user. Check that the system user becomes affiliated. 3036 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 3037 dpm.setActiveAdmin(admin1, /* replace =*/ false); 3038 assertThat(dpm.setDeviceOwner(admin1, "owner-name")).isTrue(); 3039 assertThat(dpm.isAffiliatedUser()).isTrue(); 3040 assertThat(dpm.getAffiliationIds(admin1).isEmpty()).isTrue(); 3041 3042 // Install a profile owner. Check that the test user is unaffiliated. 3043 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 3044 setAsProfileOwner(admin2); 3045 assertThat(dpm.isAffiliatedUser()).isFalse(); 3046 assertThat(dpm.getAffiliationIds(admin2).isEmpty()).isTrue(); 3047 3048 // Have the profile owner specify a set of affiliation ids. Check that the test user remains 3049 // unaffiliated. 3050 final Set<String> userAffiliationIds = new ArraySet<>(); 3051 userAffiliationIds.add("red"); 3052 userAffiliationIds.add("green"); 3053 userAffiliationIds.add("blue"); 3054 dpm.setAffiliationIds(admin2, userAffiliationIds); 3055 MoreAsserts.assertContentsInAnyOrder(dpm.getAffiliationIds(admin2), "red", "green", "blue"); 3056 assertThat(dpm.isAffiliatedUser()).isFalse(); 3057 3058 // Have the device owner specify a set of affiliation ids that do not intersect with those 3059 // specified by the profile owner. Check that the test user remains unaffiliated. 3060 final Set<String> deviceAffiliationIds = new ArraySet<>(); 3061 deviceAffiliationIds.add("cyan"); 3062 deviceAffiliationIds.add("yellow"); 3063 deviceAffiliationIds.add("magenta"); 3064 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3065 dpm.setAffiliationIds(admin1, deviceAffiliationIds); 3066 MoreAsserts.assertContentsInAnyOrder( 3067 dpm.getAffiliationIds(admin1), "cyan", "yellow", "magenta"); 3068 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 3069 assertThat(dpm.isAffiliatedUser()).isFalse(); 3070 3071 // Have the profile owner specify a set of affiliation ids that intersect with those 3072 // specified by the device owner. Check that the test user becomes affiliated. 3073 userAffiliationIds.add("yellow"); 3074 dpm.setAffiliationIds(admin2, userAffiliationIds); 3075 MoreAsserts.assertContentsInAnyOrder( 3076 dpm.getAffiliationIds(admin2), "red", "green", "blue", "yellow"); 3077 assertThat(dpm.isAffiliatedUser()).isTrue(); 3078 3079 // Clear affiliation ids for the profile owner. The user becomes unaffiliated. 3080 dpm.setAffiliationIds(admin2, Collections.emptySet()); 3081 assertThat(dpm.getAffiliationIds(admin2).isEmpty()).isTrue(); 3082 assertThat(dpm.isAffiliatedUser()).isFalse(); 3083 3084 // Set affiliation ids again, then clear PO to check that the user becomes unaffiliated 3085 dpm.setAffiliationIds(admin2, userAffiliationIds); 3086 assertThat(dpm.isAffiliatedUser()).isTrue(); 3087 dpm.clearProfileOwner(admin2); 3088 assertThat(dpm.isAffiliatedUser()).isFalse(); 3089 3090 // Check that the system user remains affiliated. 3091 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3092 assertThat(dpm.isAffiliatedUser()).isTrue(); 3093 3094 // Clear the device owner - the user becomes unaffiliated. 3095 clearDeviceOwner(); 3096 assertThat(dpm.isAffiliatedUser()).isFalse(); 3097 } 3098 3099 @Test testGetUserProvisioningState_defaultResult()3100 public void testGetUserProvisioningState_defaultResult() { 3101 mContext.callerPermissions.add(permission.MANAGE_USERS); 3102 assertThat(dpm.getUserProvisioningState()) 3103 .isEqualTo(DevicePolicyManager.STATE_USER_UNMANAGED); 3104 } 3105 3106 @Test testSetUserProvisioningState_permission()3107 public void testSetUserProvisioningState_permission() throws Exception { 3108 setupProfileOwner(); 3109 3110 exerciseUserProvisioningTransitions(CALLER_USER_HANDLE, 3111 DevicePolicyManager.STATE_USER_SETUP_FINALIZED); 3112 } 3113 3114 @Test testSetUserProvisioningState_unprivileged()3115 public void testSetUserProvisioningState_unprivileged() throws Exception { 3116 setupProfileOwner(); 3117 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 3118 () -> dpm.setUserProvisioningState(DevicePolicyManager.STATE_USER_SETUP_FINALIZED, 3119 CALLER_USER_HANDLE)); 3120 } 3121 3122 @Test testSetUserProvisioningState_noManagement()3123 public void testSetUserProvisioningState_noManagement() { 3124 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 3125 mContext.callerPermissions.add(permission.MANAGE_USERS); 3126 assertExpectException(IllegalStateException.class, 3127 /* messageRegex= */ "change provisioning state unless a .* owner is set", 3128 () -> dpm.setUserProvisioningState(DevicePolicyManager.STATE_USER_SETUP_FINALIZED, 3129 CALLER_USER_HANDLE)); 3130 assertThat(dpm.getUserProvisioningState()) 3131 .isEqualTo(DevicePolicyManager.STATE_USER_UNMANAGED); 3132 } 3133 3134 @Test testSetUserProvisioningState_deviceOwnerFromSetupWizard()3135 public void testSetUserProvisioningState_deviceOwnerFromSetupWizard() throws Exception { 3136 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3137 setupDeviceOwner(); 3138 3139 exerciseUserProvisioningTransitions(UserHandle.USER_SYSTEM, 3140 DevicePolicyManager.STATE_USER_SETUP_COMPLETE, 3141 DevicePolicyManager.STATE_USER_SETUP_FINALIZED); 3142 } 3143 3144 @Test testSetUserProvisioningState_deviceOwnerFromSetupWizardAlternative()3145 public void testSetUserProvisioningState_deviceOwnerFromSetupWizardAlternative() 3146 throws Exception { 3147 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3148 setupDeviceOwner(); 3149 3150 exerciseUserProvisioningTransitions(UserHandle.USER_SYSTEM, 3151 DevicePolicyManager.STATE_USER_SETUP_INCOMPLETE, 3152 DevicePolicyManager.STATE_USER_SETUP_FINALIZED); 3153 } 3154 3155 @Test testSetUserProvisioningState_deviceOwnerWithoutSetupWizard()3156 public void testSetUserProvisioningState_deviceOwnerWithoutSetupWizard() throws Exception { 3157 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3158 setupDeviceOwner(); 3159 3160 exerciseUserProvisioningTransitions(UserHandle.USER_SYSTEM, 3161 DevicePolicyManager.STATE_USER_SETUP_FINALIZED); 3162 } 3163 3164 @Test testSetUserProvisioningState_managedProfileFromSetupWizard_primaryUser()3165 public void testSetUserProvisioningState_managedProfileFromSetupWizard_primaryUser() 3166 throws Exception { 3167 setupProfileOwner(); 3168 3169 exerciseUserProvisioningTransitions(CALLER_USER_HANDLE, 3170 DevicePolicyManager.STATE_USER_PROFILE_COMPLETE, 3171 DevicePolicyManager.STATE_USER_PROFILE_FINALIZED); 3172 } 3173 3174 @Test testSetUserProvisioningState_managedProfileFromSetupWizard_managedProfile()3175 public void testSetUserProvisioningState_managedProfileFromSetupWizard_managedProfile() 3176 throws Exception { 3177 setupProfileOwner(); 3178 3179 exerciseUserProvisioningTransitions(CALLER_USER_HANDLE, 3180 DevicePolicyManager.STATE_USER_SETUP_COMPLETE, 3181 DevicePolicyManager.STATE_USER_SETUP_FINALIZED); 3182 } 3183 3184 @Test testSetUserProvisioningState_managedProfileWithoutSetupWizard()3185 public void testSetUserProvisioningState_managedProfileWithoutSetupWizard() throws Exception { 3186 setupProfileOwner(); 3187 3188 exerciseUserProvisioningTransitions(CALLER_USER_HANDLE, 3189 DevicePolicyManager.STATE_USER_SETUP_FINALIZED); 3190 } 3191 3192 @Test testSetUserProvisioningState_illegalTransitionOutOfFinalized1()3193 public void testSetUserProvisioningState_illegalTransitionOutOfFinalized1() throws Exception { 3194 setupProfileOwner(); 3195 3196 assertExpectException(IllegalStateException.class, 3197 /* messageRegex= */ "Cannot move to user provisioning state", 3198 () -> exerciseUserProvisioningTransitions(CALLER_USER_HANDLE, 3199 DevicePolicyManager.STATE_USER_SETUP_FINALIZED, 3200 DevicePolicyManager.STATE_USER_UNMANAGED)); 3201 } 3202 3203 @Test testSetUserProvisioningState_profileFinalized_canTransitionToUserUnmanaged()3204 public void testSetUserProvisioningState_profileFinalized_canTransitionToUserUnmanaged() 3205 throws Exception { 3206 setupProfileOwner(); 3207 3208 exerciseUserProvisioningTransitions(CALLER_USER_HANDLE, 3209 DevicePolicyManager.STATE_USER_PROFILE_FINALIZED, 3210 DevicePolicyManager.STATE_USER_UNMANAGED); 3211 } 3212 3213 @Test testSetUserProvisioningState_illegalTransitionToAnotherInProgressState()3214 public void testSetUserProvisioningState_illegalTransitionToAnotherInProgressState() 3215 throws Exception { 3216 setupProfileOwner(); 3217 3218 assertExpectException(IllegalStateException.class, 3219 /* messageRegex= */ "Cannot move to user provisioning state", 3220 () -> exerciseUserProvisioningTransitions(CALLER_USER_HANDLE, 3221 DevicePolicyManager.STATE_USER_SETUP_INCOMPLETE, 3222 DevicePolicyManager.STATE_USER_SETUP_COMPLETE)); 3223 } 3224 exerciseUserProvisioningTransitions(int userId, int... states)3225 private void exerciseUserProvisioningTransitions(int userId, int... states) { 3226 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 3227 mContext.callerPermissions.add(permission.MANAGE_USERS); 3228 3229 assertThat(dpm.getUserProvisioningState()) 3230 .isEqualTo(DevicePolicyManager.STATE_USER_UNMANAGED); 3231 for (int state : states) { 3232 dpm.setUserProvisioningState(state, userId); 3233 assertThat(dpm.getUserProvisioningState()).isEqualTo(state); 3234 } 3235 } 3236 setupProfileOwner()3237 private void setupProfileOwner() throws Exception { 3238 mContext.callerPermissions.addAll(OWNER_SETUP_PERMISSIONS); 3239 3240 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID); 3241 dpm.setActiveAdmin(admin1, false); 3242 assertThat(dpm.setProfileOwner(admin1, null, CALLER_USER_HANDLE)).isTrue(); 3243 3244 mContext.callerPermissions.removeAll(OWNER_SETUP_PERMISSIONS); 3245 } 3246 setupProfileOwnerOnUser0()3247 private void setupProfileOwnerOnUser0() throws Exception { 3248 mContext.callerPermissions.addAll(OWNER_SETUP_PERMISSIONS); 3249 3250 setUpPackageManagerForAdmin(admin1, DpmMockContext.SYSTEM_UID); 3251 dpm.setActiveAdmin(admin1, false); 3252 assertThat(dpm.setProfileOwner(admin1, null, UserHandle.USER_SYSTEM)).isTrue(); 3253 3254 mContext.callerPermissions.removeAll(OWNER_SETUP_PERMISSIONS); 3255 } 3256 setupDeviceOwner()3257 private void setupDeviceOwner() throws Exception { 3258 mContext.callerPermissions.addAll(OWNER_SETUP_PERMISSIONS); 3259 3260 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 3261 dpm.setActiveAdmin(admin1, false); 3262 assertThat(dpm.setDeviceOwner(admin1, null, UserHandle.USER_SYSTEM)).isTrue(); 3263 3264 mContext.callerPermissions.removeAll(OWNER_SETUP_PERMISSIONS); 3265 } 3266 3267 @Test testSetMaximumTimeToLock()3268 public void testSetMaximumTimeToLock() { 3269 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS); 3270 3271 dpm.setActiveAdmin(admin1, /* replace =*/ false); 3272 dpm.setActiveAdmin(admin2, /* replace =*/ false); 3273 3274 reset(getServices().powerManagerInternal); 3275 reset(getServices().settings); 3276 3277 dpm.setMaximumTimeToLock(admin1, 0); 3278 verifyScreenTimeoutCall(null, UserHandle.USER_SYSTEM); 3279 verifyStayOnWhilePluggedCleared(false); 3280 reset(getServices().powerManagerInternal); 3281 reset(getServices().settings); 3282 3283 dpm.setMaximumTimeToLock(admin1, 1); 3284 verifyScreenTimeoutCall(1L, UserHandle.USER_SYSTEM); 3285 verifyStayOnWhilePluggedCleared(true); 3286 reset(getServices().powerManagerInternal); 3287 reset(getServices().settings); 3288 3289 dpm.setMaximumTimeToLock(admin2, 10); 3290 verifyScreenTimeoutCall(null, UserHandle.USER_SYSTEM); 3291 verifyStayOnWhilePluggedCleared(false); 3292 reset(getServices().powerManagerInternal); 3293 reset(getServices().settings); 3294 3295 dpm.setMaximumTimeToLock(admin1, 5); 3296 verifyScreenTimeoutCall(5L, UserHandle.USER_SYSTEM); 3297 verifyStayOnWhilePluggedCleared(true); 3298 reset(getServices().powerManagerInternal); 3299 reset(getServices().settings); 3300 3301 dpm.setMaximumTimeToLock(admin2, 4); 3302 verifyScreenTimeoutCall(4L, UserHandle.USER_SYSTEM); 3303 verifyStayOnWhilePluggedCleared(true); 3304 reset(getServices().powerManagerInternal); 3305 reset(getServices().settings); 3306 3307 dpm.setMaximumTimeToLock(admin1, 0); 3308 reset(getServices().powerManagerInternal); 3309 reset(getServices().settings); 3310 3311 dpm.setMaximumTimeToLock(admin2, Long.MAX_VALUE); 3312 verifyScreenTimeoutCall(Long.MAX_VALUE, UserHandle.USER_SYSTEM); 3313 verifyStayOnWhilePluggedCleared(true); 3314 reset(getServices().powerManagerInternal); 3315 reset(getServices().settings); 3316 3317 dpm.setMaximumTimeToLock(admin2, 10); 3318 verifyScreenTimeoutCall(10L, UserHandle.USER_SYSTEM); 3319 verifyStayOnWhilePluggedCleared(true); 3320 reset(getServices().powerManagerInternal); 3321 reset(getServices().settings); 3322 3323 // There's no restriction; should be set to MAX. 3324 dpm.setMaximumTimeToLock(admin2, 0); 3325 verifyScreenTimeoutCall(Long.MAX_VALUE, UserHandle.USER_SYSTEM); 3326 verifyStayOnWhilePluggedCleared(false); 3327 } 3328 3329 @Test testIsActiveSupervisionApp()3330 public void testIsActiveSupervisionApp() throws Exception { 3331 when(mServiceContext.resources 3332 .getString(R.string.config_defaultSupervisionProfileOwnerComponent)) 3333 .thenReturn(admin1.flattenToString()); 3334 3335 final int PROFILE_USER = 15; 3336 final int PROFILE_ADMIN = UserHandle.getUid(PROFILE_USER, 19436); 3337 addManagedProfile(admin1, PROFILE_ADMIN, admin1); 3338 mContext.binder.callingUid = PROFILE_ADMIN; 3339 3340 final DevicePolicyManagerInternal dpmi = 3341 LocalServices.getService(DevicePolicyManagerInternal.class); 3342 assertThat(dpmi.isActiveSupervisionApp(PROFILE_ADMIN)).isTrue(); 3343 } 3344 3345 // Test if lock timeout on managed profile is handled correctly depending on whether profile 3346 // uses separate challenge. 3347 @Test testSetMaximumTimeToLockProfile()3348 public void testSetMaximumTimeToLockProfile() throws Exception { 3349 final int PROFILE_USER = 15; 3350 final int PROFILE_ADMIN = UserHandle.getUid(PROFILE_USER, 19436); 3351 addManagedProfile(admin1, PROFILE_ADMIN, admin1); 3352 mContext.binder.callingUid = PROFILE_ADMIN; 3353 final DevicePolicyManagerInternal dpmi = 3354 LocalServices.getService(DevicePolicyManagerInternal.class); 3355 3356 dpm.setMaximumTimeToLock(admin1, 0); 3357 3358 reset(getServices().powerManagerInternal); 3359 reset(getServices().settings); 3360 3361 // First add timeout for the profile. 3362 dpm.setMaximumTimeToLock(admin1, 10); 3363 verifyScreenTimeoutCall(10L, UserHandle.USER_SYSTEM); 3364 3365 reset(getServices().powerManagerInternal); 3366 reset(getServices().settings); 3367 3368 // Add separate challenge 3369 when(getServices().lockPatternUtils 3370 .isSeparateProfileChallengeEnabled(eq(PROFILE_USER))).thenReturn(true); 3371 dpmi.reportSeparateProfileChallengeChanged(PROFILE_USER); 3372 3373 verifyScreenTimeoutCall(10L, PROFILE_USER); 3374 verifyScreenTimeoutCall(Long.MAX_VALUE, UserHandle.USER_SYSTEM); 3375 3376 reset(getServices().powerManagerInternal); 3377 reset(getServices().settings); 3378 3379 // Remove the timeout. 3380 dpm.setMaximumTimeToLock(admin1, 0); 3381 verifyScreenTimeoutCall(Long.MAX_VALUE, PROFILE_USER); 3382 verifyScreenTimeoutCall(null , UserHandle.USER_SYSTEM); 3383 3384 reset(getServices().powerManagerInternal); 3385 reset(getServices().settings); 3386 3387 // Add it back. 3388 dpm.setMaximumTimeToLock(admin1, 10); 3389 verifyScreenTimeoutCall(10L, PROFILE_USER); 3390 verifyScreenTimeoutCall(null, UserHandle.USER_SYSTEM); 3391 3392 reset(getServices().powerManagerInternal); 3393 reset(getServices().settings); 3394 3395 // Remove separate challenge. 3396 reset(getServices().lockPatternUtils); 3397 when(getServices().lockPatternUtils 3398 .isSeparateProfileChallengeEnabled(eq(PROFILE_USER))).thenReturn(false); 3399 dpmi.reportSeparateProfileChallengeChanged(PROFILE_USER); 3400 when(getServices().lockPatternUtils.hasSecureLockScreen()).thenReturn(true); 3401 3402 verifyScreenTimeoutCall(Long.MAX_VALUE, PROFILE_USER); 3403 verifyScreenTimeoutCall(10L , UserHandle.USER_SYSTEM); 3404 3405 reset(getServices().powerManagerInternal); 3406 reset(getServices().settings); 3407 3408 // Remove the timeout. 3409 dpm.setMaximumTimeToLock(admin1, 0); 3410 verifyScreenTimeoutCall(null, PROFILE_USER); 3411 verifyScreenTimeoutCall(Long.MAX_VALUE, UserHandle.USER_SYSTEM); 3412 } 3413 3414 @Test testSetRequiredStrongAuthTimeout_DeviceOwner()3415 public void testSetRequiredStrongAuthTimeout_DeviceOwner() throws Exception { 3416 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3417 setupDeviceOwner(); 3418 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 3419 3420 final long MINIMUM_STRONG_AUTH_TIMEOUT_MS = TimeUnit.HOURS.toMillis(1); 3421 final long ONE_MINUTE = TimeUnit.MINUTES.toMillis(1); 3422 final long MIN_PLUS_ONE_MINUTE = MINIMUM_STRONG_AUTH_TIMEOUT_MS + ONE_MINUTE; 3423 final long MAX_MINUS_ONE_MINUTE = DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS 3424 - ONE_MINUTE; 3425 3426 // verify that the minimum timeout cannot be modified on user builds (system property is 3427 // not being read) 3428 getServices().buildMock.isDebuggable = false; 3429 3430 dpm.setRequiredStrongAuthTimeout(admin1, MAX_MINUS_ONE_MINUTE); 3431 assertThat(MAX_MINUS_ONE_MINUTE).isEqualTo(dpm.getRequiredStrongAuthTimeout(admin1)); 3432 assertThat(MAX_MINUS_ONE_MINUTE).isEqualTo(dpm.getRequiredStrongAuthTimeout(null)); 3433 3434 verify(getServices().systemProperties, never()).getLong(anyString(), anyLong()); 3435 3436 // restore to the debuggable build state 3437 getServices().buildMock.isDebuggable = true; 3438 3439 // reset to default (0 means the admin is not participating, so default should be returned) 3440 dpm.setRequiredStrongAuthTimeout(admin1, 0); 3441 3442 // aggregation should be the default if unset by any admin 3443 assertThat(DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS) 3444 .isEqualTo(dpm.getRequiredStrongAuthTimeout(null)); 3445 3446 // admin not participating by default 3447 assertThat(dpm.getRequiredStrongAuthTimeout(admin1)).isEqualTo(0); 3448 3449 //clamping from the top 3450 dpm.setRequiredStrongAuthTimeout(admin1, 3451 DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS + ONE_MINUTE); 3452 assertThat(DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS) 3453 .isEqualTo(dpm.getRequiredStrongAuthTimeout(admin1)); 3454 assertThat(DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS) 3455 .isEqualTo(dpm.getRequiredStrongAuthTimeout(null)); 3456 3457 // 0 means the admin is not participating, so default should be returned 3458 dpm.setRequiredStrongAuthTimeout(admin1, 0); 3459 assertThat(dpm.getRequiredStrongAuthTimeout(admin1)).isEqualTo(0); 3460 assertThat(DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS) 3461 .isEqualTo(dpm.getRequiredStrongAuthTimeout(null)); 3462 3463 // clamping from the bottom 3464 dpm.setRequiredStrongAuthTimeout(admin1, MINIMUM_STRONG_AUTH_TIMEOUT_MS - ONE_MINUTE); 3465 assertThat(dpm.getRequiredStrongAuthTimeout(admin1)) 3466 .isEqualTo(MINIMUM_STRONG_AUTH_TIMEOUT_MS); 3467 assertThat(dpm.getRequiredStrongAuthTimeout(null)) 3468 .isEqualTo(MINIMUM_STRONG_AUTH_TIMEOUT_MS); 3469 3470 // values within range 3471 dpm.setRequiredStrongAuthTimeout(admin1, MIN_PLUS_ONE_MINUTE); 3472 assertThat(dpm.getRequiredStrongAuthTimeout(admin1)).isEqualTo(MIN_PLUS_ONE_MINUTE); 3473 assertThat(dpm.getRequiredStrongAuthTimeout(null)).isEqualTo(MIN_PLUS_ONE_MINUTE); 3474 3475 dpm.setRequiredStrongAuthTimeout(admin1, MAX_MINUS_ONE_MINUTE); 3476 assertThat(dpm.getRequiredStrongAuthTimeout(admin1)).isEqualTo(MAX_MINUS_ONE_MINUTE); 3477 assertThat(dpm.getRequiredStrongAuthTimeout(null)).isEqualTo(MAX_MINUS_ONE_MINUTE); 3478 3479 // reset to default 3480 dpm.setRequiredStrongAuthTimeout(admin1, 0); 3481 assertThat(dpm.getRequiredStrongAuthTimeout(admin1)).isEqualTo(0); 3482 assertThat(DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS) 3483 .isEqualTo(dpm.getRequiredStrongAuthTimeout(null)); 3484 3485 // negative value 3486 assertExpectException(IllegalArgumentException.class, /* messageRegex= */ null, 3487 () -> dpm.setRequiredStrongAuthTimeout(admin1, -ONE_MINUTE)); 3488 } 3489 verifyScreenTimeoutCall(Long expectedTimeout, int userId)3490 private void verifyScreenTimeoutCall(Long expectedTimeout, int userId) { 3491 if (expectedTimeout == null) { 3492 verify(getServices().powerManagerInternal, times(0)) 3493 .setMaximumScreenOffTimeoutFromDeviceAdmin(eq(userId), anyLong()); 3494 } else { 3495 verify(getServices().powerManagerInternal, times(1)) 3496 .setMaximumScreenOffTimeoutFromDeviceAdmin(eq(userId), eq(expectedTimeout)); 3497 } 3498 } 3499 verifyStayOnWhilePluggedCleared(boolean cleared)3500 private void verifyStayOnWhilePluggedCleared(boolean cleared) { 3501 // TODO Verify calls to settingsGlobalPutInt. Tried but somehow mockito threw 3502 // UnfinishedVerificationException. 3503 } 3504 setup_DeviceAdminFeatureOff()3505 private void setup_DeviceAdminFeatureOff() throws Exception { 3506 when(getServices().packageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN)) 3507 .thenReturn(false); 3508 when(getServices().ipackageManager 3509 .hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)).thenReturn(false); 3510 initializeDpms(); 3511 when(getServices().userManagerForMock.isHeadlessSystemUserMode()).thenReturn(true); 3512 when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true)) 3513 .thenReturn(true); 3514 setUserSetupCompleteForUser(false, UserHandle.USER_SYSTEM); 3515 3516 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3517 } 3518 3519 @Test testIsProvisioningAllowed_DeviceAdminFeatureOff()3520 public void testIsProvisioningAllowed_DeviceAdminFeatureOff() throws Exception { 3521 setup_DeviceAdminFeatureOff(); 3522 mContext.packageName = admin1.getPackageName(); 3523 setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid); 3524 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, false); 3525 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_FINANCED_DEVICE, false); 3526 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false); 3527 3528 when(getServices().userManagerForMock.isHeadlessSystemUserMode()).thenReturn(true); 3529 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, false); 3530 } 3531 3532 @Test testCheckProvisioningPreCondition_DeviceAdminFeatureOff()3533 public void testCheckProvisioningPreCondition_DeviceAdminFeatureOff() throws Exception { 3534 setup_DeviceAdminFeatureOff(); 3535 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 3536 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, 3537 DevicePolicyManager.CODE_DEVICE_ADMIN_NOT_SUPPORTED); 3538 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_FINANCED_DEVICE, 3539 DevicePolicyManager.CODE_DEVICE_ADMIN_NOT_SUPPORTED); 3540 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 3541 DevicePolicyManager.CODE_DEVICE_ADMIN_NOT_SUPPORTED); 3542 } 3543 setup_ManagedProfileFeatureOff()3544 private void setup_ManagedProfileFeatureOff() throws Exception { 3545 when(getServices().ipackageManager 3546 .hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)).thenReturn(false); 3547 initializeDpms(); 3548 when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true)) 3549 .thenReturn(true); 3550 setUserSetupCompleteForUser(false, UserHandle.USER_SYSTEM); 3551 3552 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3553 } 3554 3555 @Test testIsProvisioningAllowed_ManagedProfileFeatureOff()3556 public void testIsProvisioningAllowed_ManagedProfileFeatureOff() throws Exception { 3557 setup_ManagedProfileFeatureOff(); 3558 mContext.packageName = admin1.getPackageName(); 3559 setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid); 3560 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, true); 3561 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_FINANCED_DEVICE, true); 3562 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false); 3563 3564 when(getServices().userManagerForMock.isHeadlessSystemUserMode()).thenReturn(true); 3565 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false); 3566 } 3567 3568 @Test testCheckProvisioningPreCondition_ManagedProfileFeatureOff()3569 public void testCheckProvisioningPreCondition_ManagedProfileFeatureOff() throws Exception { 3570 setup_ManagedProfileFeatureOff(); 3571 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 3572 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, 3573 DevicePolicyManager.CODE_OK); 3574 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_FINANCED_DEVICE, 3575 DevicePolicyManager.CODE_OK); 3576 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 3577 DevicePolicyManager.CODE_MANAGED_USERS_NOT_SUPPORTED); 3578 } 3579 setup_firstBoot_systemUser()3580 private void setup_firstBoot_systemUser() throws Exception { 3581 when(getServices().ipackageManager 3582 .hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)).thenReturn(true); 3583 when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, false)) 3584 .thenReturn(true); 3585 setUserSetupCompleteForUser(false, UserHandle.USER_SYSTEM); 3586 when(getServices().userManager.getProfileParent(UserHandle.USER_SYSTEM)).thenReturn(null); 3587 3588 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3589 } 3590 3591 /* Tests provisions from system user during first boot. */ 3592 @Test testIsProvisioningAllowed_firstBoot_systemUser()3593 public void testIsProvisioningAllowed_firstBoot_systemUser() throws Exception { 3594 setup_firstBoot_systemUser(); 3595 mContext.packageName = admin1.getPackageName(); 3596 setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid); 3597 3598 when(getServices().userManagerForMock.isHeadlessSystemUserMode()).thenReturn(false); 3599 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, true); 3600 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_FINANCED_DEVICE, true); 3601 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true); 3602 3603 when(getServices().userManagerForMock.isHeadlessSystemUserMode()).thenReturn(true); 3604 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, true); 3605 } 3606 3607 @Test testCheckProvisioningPreCondition_firstBoot_systemUser()3608 public void testCheckProvisioningPreCondition_firstBoot_systemUser() 3609 throws Exception { 3610 setup_firstBoot_systemUser(); 3611 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 3612 3613 when(getServices().userManagerForMock.isHeadlessSystemUserMode()).thenReturn(false); 3614 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, 3615 DevicePolicyManager.CODE_OK); 3616 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_FINANCED_DEVICE, 3617 DevicePolicyManager.CODE_OK); 3618 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 3619 DevicePolicyManager.CODE_OK); 3620 3621 when(getServices().userManagerForMock.isHeadlessSystemUserMode()).thenReturn(true); 3622 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, 3623 DevicePolicyManager.CODE_OK); 3624 } 3625 setup_systemUserSetupComplete_systemUser()3626 private void setup_systemUserSetupComplete_systemUser() throws Exception { 3627 when(getServices().ipackageManager 3628 .hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)).thenReturn(true); 3629 when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, false)) 3630 .thenReturn(true); 3631 setUserSetupCompleteForUser(true, UserHandle.USER_SYSTEM); 3632 when(getServices().userManager.getProfileParent(UserHandle.USER_SYSTEM)).thenReturn(null); 3633 3634 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3635 } 3636 setup_withDo_systemUser()3637 private void setup_withDo_systemUser() throws Exception { 3638 setDeviceOwner(); 3639 setup_systemUserSetupComplete_systemUser(); 3640 setUpPackageManagerForFakeAdmin(adminAnotherPackage, DpmMockContext.ANOTHER_UID, admin2); 3641 } 3642 setup_withDo_systemUser_ManagedProfile()3643 private void setup_withDo_systemUser_ManagedProfile() throws Exception { 3644 setup_withDo_systemUser(); 3645 final int MANAGED_PROFILE_USER_ID = 18; 3646 final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 1308); 3647 when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, 3648 false /* we can't remove a managed profile */)).thenReturn(false); 3649 } 3650 3651 @Test testIsProvisioningAllowed_systemUserSetupComplete_systemUser()3652 public void testIsProvisioningAllowed_systemUserSetupComplete_systemUser() 3653 throws Exception { 3654 setup_systemUserSetupComplete_systemUser(); 3655 mContext.packageName = admin1.getPackageName(); 3656 setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid); 3657 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, 3658 false/* because of completed device setup */); 3659 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_FINANCED_DEVICE, 3660 false/* because of completed device setup */); 3661 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true); 3662 } 3663 3664 @Test testCheckProvisioningPreCondition_systemUserSetupComplete_systemUser()3665 public void testCheckProvisioningPreCondition_systemUserSetupComplete_systemUser() 3666 throws Exception { 3667 setup_systemUserSetupComplete_systemUser(); 3668 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 3669 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, 3670 DevicePolicyManager.CODE_USER_SETUP_COMPLETED); 3671 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_FINANCED_DEVICE, 3672 DevicePolicyManager.CODE_USER_SETUP_COMPLETED); 3673 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 3674 DevicePolicyManager.CODE_OK); 3675 } 3676 3677 @Test testProvisioning_withDo_systemUser()3678 public void testProvisioning_withDo_systemUser() throws Exception { 3679 setup_withDo_systemUser(); 3680 mContext.packageName = admin1.getPackageName(); 3681 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 3682 3683 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, 3684 DevicePolicyManager.CODE_HAS_DEVICE_OWNER); 3685 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_FINANCED_DEVICE, 3686 DevicePolicyManager.CODE_HAS_DEVICE_OWNER); 3687 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, false); 3688 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_FINANCED_DEVICE, false); 3689 3690 // COMP mode NOT is allowed. 3691 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 3692 DevicePolicyManager.CODE_CANNOT_ADD_MANAGED_PROFILE); 3693 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false); 3694 3695 // And other DPCs can NOT provision a managed profile. 3696 assertCheckProvisioningPreCondition( 3697 DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 3698 DpmMockContext.ANOTHER_PACKAGE_NAME, 3699 DevicePolicyManager.CODE_CANNOT_ADD_MANAGED_PROFILE); 3700 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false, 3701 DpmMockContext.ANOTHER_PACKAGE_NAME, DpmMockContext.ANOTHER_UID); 3702 } 3703 3704 @Test testProvisioning_withDo_systemUser_restrictedBySystem()3705 public void testProvisioning_withDo_systemUser_restrictedBySystem() 3706 throws Exception { 3707 setup_withDo_systemUser(); 3708 mContext.packageName = admin1.getPackageName(); 3709 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 3710 // The DO should not be allowed to initiate provisioning if the restriction is set by 3711 // another entity. 3712 when(getServices().userManager.hasUserRestriction( 3713 eq(UserManager.DISALLOW_ADD_MANAGED_PROFILE), 3714 eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid)))) 3715 .thenReturn(true); 3716 when(getServices().userManager.getUserRestrictionSource( 3717 eq(UserManager.DISALLOW_ADD_MANAGED_PROFILE), 3718 eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid)))) 3719 .thenReturn(UserManager.RESTRICTION_SOURCE_SYSTEM); 3720 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 3721 DevicePolicyManager.CODE_CANNOT_ADD_MANAGED_PROFILE); 3722 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false); 3723 3724 assertCheckProvisioningPreCondition( 3725 DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 3726 DpmMockContext.ANOTHER_PACKAGE_NAME, 3727 DevicePolicyManager.CODE_CANNOT_ADD_MANAGED_PROFILE); 3728 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false, 3729 DpmMockContext.ANOTHER_PACKAGE_NAME, DpmMockContext.ANOTHER_UID); 3730 } 3731 3732 @Test testCheckCannotSetProfileOwnerWithDeviceOwner()3733 public void testCheckCannotSetProfileOwnerWithDeviceOwner() throws Exception { 3734 setup_withDo_systemUser(); 3735 final int managedProfileUserId = 18; 3736 final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 1308); 3737 3738 final int userId = UserHandle.getUserId(managedProfileAdminUid); 3739 getServices().addUser(userId, 0, UserManager.USER_TYPE_PROFILE_MANAGED, 3740 UserHandle.USER_SYSTEM); 3741 mContext.callerPermissions.addAll(OWNER_SETUP_PERMISSIONS); 3742 setUpPackageManagerForFakeAdmin(admin1, managedProfileAdminUid, admin1); 3743 dpm.setActiveAdmin(admin1, false, userId); 3744 assertThat(dpm.setProfileOwner(admin1, null, userId)).isFalse(); 3745 mContext.callerPermissions.removeAll(OWNER_SETUP_PERMISSIONS); 3746 } 3747 3748 @Test testCheckProvisioningPreCondition_attemptingComp()3749 public void testCheckProvisioningPreCondition_attemptingComp() throws Exception { 3750 setup_withDo_systemUser_ManagedProfile(); 3751 mContext.packageName = admin1.getPackageName(); 3752 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 3753 3754 // We can delete the managed profile to create a new one, so provisioning is allowed. 3755 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 3756 DevicePolicyManager.CODE_CANNOT_ADD_MANAGED_PROFILE); 3757 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false); 3758 assertCheckProvisioningPreCondition( 3759 DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 3760 DpmMockContext.ANOTHER_PACKAGE_NAME, 3761 DevicePolicyManager.CODE_CANNOT_ADD_MANAGED_PROFILE); 3762 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false, 3763 DpmMockContext.ANOTHER_PACKAGE_NAME, DpmMockContext.ANOTHER_UID); 3764 } 3765 3766 @Test testCheckProvisioningPreCondition_comp_cannot_remove_profile()3767 public void testCheckProvisioningPreCondition_comp_cannot_remove_profile() 3768 throws Exception { 3769 setup_withDo_systemUser_ManagedProfile(); 3770 mContext.packageName = admin1.getPackageName(); 3771 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 3772 when(getServices().userManager.hasUserRestriction( 3773 eq(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE), 3774 eq(UserHandle.SYSTEM))) 3775 .thenReturn(true); 3776 when(getServices().userManager.getUserRestrictionSource( 3777 eq(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE), 3778 eq(UserHandle.SYSTEM))) 3779 .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER); 3780 3781 // We can't remove the profile to create a new one. 3782 assertCheckProvisioningPreCondition( 3783 DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 3784 DpmMockContext.ANOTHER_PACKAGE_NAME, 3785 DevicePolicyManager.CODE_CANNOT_ADD_MANAGED_PROFILE); 3786 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false, 3787 DpmMockContext.ANOTHER_PACKAGE_NAME, DpmMockContext.ANOTHER_UID); 3788 3789 // But the device owner can still do it because it has set the restriction itself. 3790 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 3791 DevicePolicyManager.CODE_CANNOT_ADD_MANAGED_PROFILE); 3792 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false); 3793 } 3794 3795 // TODO(b/174859111): move to automotive-only section setup_firstBoot_headlessSystemUserMode()3796 private void setup_firstBoot_headlessSystemUserMode() throws Exception { 3797 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 3798 when(getServices().userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, false)) 3799 .thenReturn(true); 3800 setUserSetupCompleteForUser(false, UserHandle.USER_SYSTEM); 3801 when(getServices().userManager.getProfileParent(UserHandle.USER_SYSTEM)).thenReturn(null); 3802 } 3803 3804 /** 3805 * TODO(b/174859111): move to automotive-only section 3806 * Tests provision from secondary user during first boot. 3807 **/ 3808 @Test testIsProvisioningAllowed_firstBoot_secondaryUser()3809 public void testIsProvisioningAllowed_firstBoot_secondaryUser() throws Exception { 3810 setup_firstBoot_headlessSystemUserMode(); 3811 mContext.packageName = admin1.getPackageName(); 3812 setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid); 3813 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 3814 // Provisioning device from secondary user should fail in non-headless system user mode. 3815 when(getServices().userManagerForMock.isHeadlessSystemUserMode()).thenReturn(false); 3816 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, false); 3817 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_FINANCED_DEVICE, false); 3818 3819 // Required for ACTION_PROVISION_MANAGED_PROFILE if allowed to add managed profile from 3820 // secondary user 3821 when(getServices().userManager.canAddMoreManagedProfiles(CALLER_USER_HANDLE, false)) 3822 .thenReturn(true); 3823 when(getServices().ipackageManager 3824 .hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)).thenReturn(true); 3825 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true); 3826 3827 // Provisioning device from secondary user should be allowed in headless system user mode. 3828 when(getServices().userManagerForMock.isHeadlessSystemUserMode()).thenReturn(true); 3829 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, true); 3830 } 3831 setup_provisionManagedProfileWithDeviceOwner_primaryUser()3832 private void setup_provisionManagedProfileWithDeviceOwner_primaryUser() throws Exception { 3833 setDeviceOwner(); 3834 3835 when(getServices().ipackageManager 3836 .hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)).thenReturn(true); 3837 when(getServices().userManager.getProfileParent(CALLER_USER_HANDLE)) 3838 .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0)); 3839 when(getServices().userManager.canAddMoreManagedProfiles(CALLER_USER_HANDLE, 3840 false)).thenReturn(true); 3841 setUserSetupCompleteForUser(false, CALLER_USER_HANDLE); 3842 3843 mContext.binder.callingUid = DpmMockContext.ANOTHER_UID; 3844 } 3845 3846 @Test testIsProvisioningAllowed_provisionManagedProfileWithDeviceOwner_primaryUser()3847 public void testIsProvisioningAllowed_provisionManagedProfileWithDeviceOwner_primaryUser() 3848 throws Exception { 3849 setup_provisionManagedProfileWithDeviceOwner_primaryUser(); 3850 setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid); 3851 mContext.packageName = admin1.getPackageName(); 3852 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false); 3853 } 3854 3855 @Test testCheckProvisioningPreCondition_provisionManagedProfileWithDeviceOwner_primaryUser()3856 public void testCheckProvisioningPreCondition_provisionManagedProfileWithDeviceOwner_primaryUser() 3857 throws Exception { 3858 setup_provisionManagedProfileWithDeviceOwner_primaryUser(); 3859 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 3860 3861 // COMP mode is NOT allowed. 3862 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 3863 DevicePolicyManager.CODE_CANNOT_ADD_MANAGED_PROFILE); 3864 } 3865 setup_provisionManagedProfileOneAlreadyExist_primaryUser()3866 private void setup_provisionManagedProfileOneAlreadyExist_primaryUser() throws Exception { 3867 setDeviceOwner(); 3868 3869 when(getServices().ipackageManager 3870 .hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0)).thenReturn(true); 3871 when(getServices().userManager.hasUserRestriction( 3872 eq(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE), 3873 eq(UserHandle.of(CALLER_USER_HANDLE)))) 3874 .thenReturn(true); 3875 when(getServices().userManager.canAddMoreManagedProfiles(CALLER_USER_HANDLE, 3876 false /* we can't remove a managed profile */)).thenReturn(false); 3877 setUserSetupCompleteForUser(false, CALLER_USER_HANDLE); 3878 3879 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 3880 } 3881 3882 @Test testIsProvisioningAllowed_provisionManagedProfile_oneAlreadyExists_primaryUser()3883 public void testIsProvisioningAllowed_provisionManagedProfile_oneAlreadyExists_primaryUser() 3884 throws Exception { 3885 setup_provisionManagedProfileOneAlreadyExist_primaryUser(); 3886 mContext.packageName = admin1.getPackageName(); 3887 setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid); 3888 assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false); 3889 } 3890 3891 @Test testCheckProvisioningPreCondition_provisionManagedProfile_oneAlreadyExists_primaryUser()3892 public void testCheckProvisioningPreCondition_provisionManagedProfile_oneAlreadyExists_primaryUser() 3893 throws Exception { 3894 setup_provisionManagedProfileOneAlreadyExist_primaryUser(); 3895 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 3896 assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, 3897 DevicePolicyManager.CODE_CANNOT_ADD_MANAGED_PROFILE); 3898 } 3899 3900 @Test testCheckProvisioningPreCondition_permission()3901 public void testCheckProvisioningPreCondition_permission() { 3902 // GIVEN the permission MANAGE_PROFILE_AND_DEVICE_OWNERS is not granted 3903 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 3904 () -> dpm.checkProvisioningPreCondition( 3905 DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, "some.package")); 3906 } 3907 3908 @Test testForceUpdateUserSetupComplete_permission()3909 public void testForceUpdateUserSetupComplete_permission() { 3910 // GIVEN the permission MANAGE_PROFILE_AND_DEVICE_OWNERS is not granted 3911 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 3912 () -> dpm.forceUpdateUserSetupComplete(UserHandle.USER_SYSTEM)); 3913 } 3914 3915 @Test testForceUpdateUserSetupComplete_forcesUpdate()3916 public void testForceUpdateUserSetupComplete_forcesUpdate() { 3917 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS); 3918 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3919 final int userId = UserHandle.getUserId(mContext.binder.callingUid); 3920 3921 // GIVEN userComplete is false in SettingsProvider 3922 setUserSetupCompleteForUser(false, userId); 3923 3924 // GIVEN userComplete is true in DPM 3925 DevicePolicyData userData = new DevicePolicyData(userId); 3926 userData.mUserSetupComplete = true; 3927 dpms.mUserData.put(userId, userData); 3928 3929 assertThat(dpms.hasUserSetupCompleted()).isTrue(); 3930 3931 dpm.forceUpdateUserSetupComplete(userId); 3932 3933 // THEN the state in dpms is changed 3934 assertThat(dpms.hasUserSetupCompleted()).isFalse(); 3935 } 3936 clearDeviceOwner()3937 private void clearDeviceOwner() throws Exception { 3938 doReturn(DpmMockContext.CALLER_SYSTEM_USER_UID).when(getServices().packageManager) 3939 .getPackageUidAsUser(eq(admin1.getPackageName()), anyInt()); 3940 3941 mAdmin1Context.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3942 runAsCaller(mAdmin1Context, dpms, dpm -> { 3943 dpm.clearDeviceOwnerApp(admin1.getPackageName()); 3944 }); 3945 } 3946 3947 @Test testGetLastSecurityLogRetrievalTime()3948 public void testGetLastSecurityLogRetrievalTime() throws Exception { 3949 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 3950 setupDeviceOwner(); 3951 3952 // setUp() adds a secondary user for CALLER_USER_HANDLE. Remove it as otherwise the 3953 // feature is disabled because there are non-affiliated secondary users. 3954 getServices().removeUser(CALLER_USER_HANDLE); 3955 when(mContext.resources.getBoolean(R.bool.config_supportPreRebootSecurityLogs)) 3956 .thenReturn(true); 3957 3958 // No logs were retrieved so far. 3959 assertThat(dpm.getLastSecurityLogRetrievalTime()).isEqualTo(-1); 3960 3961 // Enabling logging should not change the timestamp. 3962 dpm.setSecurityLoggingEnabled(admin1, true); 3963 verify(getServices().settings).securityLogSetLoggingEnabledProperty(true); 3964 3965 when(getServices().settings.securityLogGetLoggingEnabledProperty()).thenReturn(true); 3966 assertThat(dpm.getLastSecurityLogRetrievalTime()).isEqualTo(-1); 3967 3968 // Retrieving the logs should update the timestamp. 3969 final long beforeRetrieval = System.currentTimeMillis(); 3970 dpm.retrieveSecurityLogs(admin1); 3971 final long firstSecurityLogRetrievalTime = dpm.getLastSecurityLogRetrievalTime(); 3972 final long afterRetrieval = System.currentTimeMillis(); 3973 assertThat(firstSecurityLogRetrievalTime >= beforeRetrieval).isTrue(); 3974 assertThat(firstSecurityLogRetrievalTime <= afterRetrieval).isTrue(); 3975 3976 // Retrieving the pre-boot logs should update the timestamp. 3977 Thread.sleep(2); 3978 dpm.retrievePreRebootSecurityLogs(admin1); 3979 final long secondSecurityLogRetrievalTime = dpm.getLastSecurityLogRetrievalTime(); 3980 assertThat(secondSecurityLogRetrievalTime > firstSecurityLogRetrievalTime).isTrue(); 3981 3982 // Checking the timestamp again should not change it. 3983 Thread.sleep(2); 3984 assertThat(dpm.getLastSecurityLogRetrievalTime()).isEqualTo(secondSecurityLogRetrievalTime); 3985 3986 // Retrieving the logs again should update the timestamp. 3987 dpm.retrieveSecurityLogs(admin1); 3988 final long thirdSecurityLogRetrievalTime = dpm.getLastSecurityLogRetrievalTime(); 3989 assertThat(thirdSecurityLogRetrievalTime > secondSecurityLogRetrievalTime).isTrue(); 3990 3991 // Disabling logging should not change the timestamp. 3992 Thread.sleep(2); 3993 dpm.setSecurityLoggingEnabled(admin1, false); 3994 assertThat(dpm.getLastSecurityLogRetrievalTime()).isEqualTo(thirdSecurityLogRetrievalTime); 3995 3996 // Restarting the DPMS should not lose the timestamp. 3997 initializeDpms(); 3998 assertThat(dpm.getLastSecurityLogRetrievalTime()).isEqualTo(thirdSecurityLogRetrievalTime); 3999 4000 // Any uid holding MANAGE_USERS permission can retrieve the timestamp. 4001 mContext.binder.callingUid = 1234567; 4002 mContext.callerPermissions.add(permission.MANAGE_USERS); 4003 assertThat(dpm.getLastSecurityLogRetrievalTime()).isEqualTo(thirdSecurityLogRetrievalTime); 4004 mContext.callerPermissions.remove(permission.MANAGE_USERS); 4005 4006 // System can retrieve the timestamp. 4007 mContext.binder.clearCallingIdentity(); 4008 assertThat(dpm.getLastSecurityLogRetrievalTime()).isEqualTo(thirdSecurityLogRetrievalTime); 4009 4010 // Removing the device owner should clear the timestamp. 4011 clearDeviceOwner(); 4012 assertThat(dpm.getLastSecurityLogRetrievalTime()).isEqualTo(-1); 4013 } 4014 4015 @Test testSetConfiguredNetworksLockdownStateWithDO()4016 public void testSetConfiguredNetworksLockdownStateWithDO() throws Exception { 4017 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 4018 setupDeviceOwner(); 4019 dpm.setConfiguredNetworksLockdownState(admin1, true); 4020 verify(getServices().settings).settingsGlobalPutInt( 4021 Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN, 1); 4022 4023 dpm.setConfiguredNetworksLockdownState(admin1, false); 4024 verify(getServices().settings).settingsGlobalPutInt( 4025 Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN, 0); 4026 } 4027 4028 @Test testSetConfiguredNetworksLockdownStateWithPO()4029 public void testSetConfiguredNetworksLockdownStateWithPO() throws Exception { 4030 setupProfileOwner(); 4031 assertExpectException(SecurityException.class, null, 4032 () -> dpm.setConfiguredNetworksLockdownState(admin1, false)); 4033 verify(getServices().settings, never()).settingsGlobalPutInt( 4034 Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN, 0); 4035 } 4036 4037 @Test testSetConfiguredNetworksLockdownStateWithPOOfOrganizationOwnedDevice()4038 public void testSetConfiguredNetworksLockdownStateWithPOOfOrganizationOwnedDevice() 4039 throws Exception { 4040 setupProfileOwner(); 4041 configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE); 4042 dpm.setConfiguredNetworksLockdownState(admin1, true); 4043 verify(getServices().settings).settingsGlobalPutInt( 4044 Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN, 1); 4045 4046 dpm.setConfiguredNetworksLockdownState(admin1, false); 4047 verify(getServices().settings).settingsGlobalPutInt( 4048 Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN, 0); 4049 } 4050 4051 @Test testUpdateNetworkPreferenceOnStartUser()4052 public void testUpdateNetworkPreferenceOnStartUser() throws Exception { 4053 final int managedProfileUserId = 15; 4054 final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); 4055 addManagedProfile(admin1, managedProfileAdminUid, admin1); 4056 mContext.binder.callingUid = managedProfileAdminUid; 4057 mServiceContext.permissions.add(permission.INTERACT_ACROSS_USERS_FULL); 4058 4059 dpms.handleStartUser(managedProfileUserId); 4060 verify(getServices().connectivityManager, times(1)).setProfileNetworkPreference( 4061 eq(UserHandle.of(managedProfileUserId)), 4062 anyInt(), 4063 any(), 4064 any() 4065 ); 4066 } 4067 4068 @Test testUpdateNetworkPreferenceOnStopUser()4069 public void testUpdateNetworkPreferenceOnStopUser() throws Exception { 4070 final int managedProfileUserId = 15; 4071 final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); 4072 addManagedProfile(admin1, managedProfileAdminUid, admin1); 4073 mContext.binder.callingUid = managedProfileAdminUid; 4074 mServiceContext.permissions.add(permission.INTERACT_ACROSS_USERS_FULL); 4075 4076 dpms.handleStopUser(managedProfileUserId); 4077 verify(getServices().connectivityManager, times(1)).setProfileNetworkPreference( 4078 eq(UserHandle.of(managedProfileUserId)), 4079 eq(ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT), 4080 any(), 4081 any() 4082 ); 4083 } 4084 4085 @Test testGetSetPreferentialNetworkService()4086 public void testGetSetPreferentialNetworkService() throws Exception { 4087 assertExpectException(SecurityException.class, null, 4088 () -> dpm.setPreferentialNetworkServiceEnabled(false)); 4089 4090 assertExpectException(SecurityException.class, null, 4091 () -> dpm.isPreferentialNetworkServiceEnabled()); 4092 4093 final int managedProfileUserId = 15; 4094 final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); 4095 addManagedProfile(admin1, managedProfileAdminUid, admin1); 4096 mContext.binder.callingUid = managedProfileAdminUid; 4097 4098 dpm.setPreferentialNetworkServiceEnabled(false); 4099 assertThat(dpm.isPreferentialNetworkServiceEnabled()).isFalse(); 4100 verify(getServices().connectivityManager, times(1)).setProfileNetworkPreference( 4101 eq(UserHandle.of(managedProfileUserId)), 4102 eq(ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT), 4103 any(), 4104 any() 4105 ); 4106 4107 dpm.setPreferentialNetworkServiceEnabled(true); 4108 assertThat(dpm.isPreferentialNetworkServiceEnabled()).isTrue(); 4109 verify(getServices().connectivityManager, times(1)).setProfileNetworkPreference( 4110 eq(UserHandle.of(managedProfileUserId)), 4111 eq(ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE), 4112 any(), 4113 any() 4114 ); 4115 } 4116 4117 @Test testSetSystemSettingFailWithNonWhitelistedSettings()4118 public void testSetSystemSettingFailWithNonWhitelistedSettings() throws Exception { 4119 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 4120 setupDeviceOwner(); 4121 assertExpectException(SecurityException.class, null, () -> 4122 dpm.setSystemSetting(admin1, Settings.System.SCREEN_BRIGHTNESS_FOR_VR, "0")); 4123 } 4124 4125 @Test testSetSystemSettingWithDO()4126 public void testSetSystemSettingWithDO() throws Exception { 4127 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 4128 setupDeviceOwner(); 4129 dpm.setSystemSetting(admin1, Settings.System.SCREEN_BRIGHTNESS, "0"); 4130 verify(getServices().settings).settingsSystemPutStringForUser( 4131 Settings.System.SCREEN_BRIGHTNESS, "0", UserHandle.USER_SYSTEM); 4132 } 4133 4134 @Test testSetSystemSettingWithPO()4135 public void testSetSystemSettingWithPO() throws Exception { 4136 setupProfileOwner(); 4137 dpm.setSystemSetting(admin1, Settings.System.SCREEN_BRIGHTNESS, "0"); 4138 verify(getServices().settings).settingsSystemPutStringForUser( 4139 Settings.System.SCREEN_BRIGHTNESS, "0", CALLER_USER_HANDLE); 4140 } 4141 4142 @Test testSetAutoTimeEnabledModifiesSetting()4143 public void testSetAutoTimeEnabledModifiesSetting() throws Exception { 4144 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 4145 setupDeviceOwner(); 4146 dpm.setAutoTimeEnabled(admin1, true); 4147 verify(getServices().settings).settingsGlobalPutInt(Settings.Global.AUTO_TIME, 1); 4148 4149 dpm.setAutoTimeEnabled(admin1, false); 4150 verify(getServices().settings).settingsGlobalPutInt(Settings.Global.AUTO_TIME, 0); 4151 } 4152 4153 @Test testSetAutoTimeEnabledWithPOOnUser0()4154 public void testSetAutoTimeEnabledWithPOOnUser0() throws Exception { 4155 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 4156 setupProfileOwnerOnUser0(); 4157 dpm.setAutoTimeEnabled(admin1, true); 4158 verify(getServices().settings).settingsGlobalPutInt(Settings.Global.AUTO_TIME, 1); 4159 4160 dpm.setAutoTimeEnabled(admin1, false); 4161 verify(getServices().settings).settingsGlobalPutInt(Settings.Global.AUTO_TIME, 0); 4162 } 4163 4164 @Test testSetAutoTimeEnabledFailWithPONotOnUser0()4165 public void testSetAutoTimeEnabledFailWithPONotOnUser0() throws Exception { 4166 setupProfileOwner(); 4167 assertExpectException(SecurityException.class, null, 4168 () -> dpm.setAutoTimeEnabled(admin1, false)); 4169 verify(getServices().settings, never()).settingsGlobalPutInt(Settings.Global.AUTO_TIME, 0); 4170 } 4171 4172 @Test testSetAutoTimeEnabledWithPOOfOrganizationOwnedDevice()4173 public void testSetAutoTimeEnabledWithPOOfOrganizationOwnedDevice() throws Exception { 4174 setupProfileOwner(); 4175 configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE); 4176 4177 dpm.setAutoTimeEnabled(admin1, true); 4178 verify(getServices().settings).settingsGlobalPutInt(Settings.Global.AUTO_TIME, 1); 4179 4180 dpm.setAutoTimeEnabled(admin1, false); 4181 verify(getServices().settings).settingsGlobalPutInt(Settings.Global.AUTO_TIME, 0); 4182 } 4183 4184 @Test testSetAutoTimeZoneEnabledModifiesSetting()4185 public void testSetAutoTimeZoneEnabledModifiesSetting() throws Exception { 4186 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 4187 setupDeviceOwner(); 4188 dpm.setAutoTimeZoneEnabled(admin1, true); 4189 verify(getServices().settings).settingsGlobalPutInt(Settings.Global.AUTO_TIME_ZONE, 1); 4190 4191 dpm.setAutoTimeZoneEnabled(admin1, false); 4192 verify(getServices().settings).settingsGlobalPutInt(Settings.Global.AUTO_TIME_ZONE, 0); 4193 } 4194 4195 @Test testSetAutoTimeZoneEnabledWithPOOnUser0()4196 public void testSetAutoTimeZoneEnabledWithPOOnUser0() throws Exception { 4197 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 4198 setupProfileOwnerOnUser0(); 4199 dpm.setAutoTimeZoneEnabled(admin1, true); 4200 verify(getServices().settings).settingsGlobalPutInt(Settings.Global.AUTO_TIME_ZONE, 1); 4201 4202 dpm.setAutoTimeZoneEnabled(admin1, false); 4203 verify(getServices().settings).settingsGlobalPutInt(Settings.Global.AUTO_TIME_ZONE, 0); 4204 } 4205 4206 @Test testSetAutoTimeZoneEnabledFailWithPONotOnUser0()4207 public void testSetAutoTimeZoneEnabledFailWithPONotOnUser0() throws Exception { 4208 setupProfileOwner(); 4209 assertExpectException(SecurityException.class, null, 4210 () -> dpm.setAutoTimeZoneEnabled(admin1, false)); 4211 verify(getServices().settings, never()).settingsGlobalPutInt(Settings.Global.AUTO_TIME_ZONE, 4212 0); 4213 } 4214 4215 @Test testSetAutoTimeZoneEnabledWithPOOfOrganizationOwnedDevice()4216 public void testSetAutoTimeZoneEnabledWithPOOfOrganizationOwnedDevice() throws Exception { 4217 setupProfileOwner(); 4218 configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE); 4219 4220 dpm.setAutoTimeZoneEnabled(admin1, true); 4221 verify(getServices().settings).settingsGlobalPutInt(Settings.Global.AUTO_TIME_ZONE, 1); 4222 4223 dpm.setAutoTimeZoneEnabled(admin1, false); 4224 verify(getServices().settings).settingsGlobalPutInt(Settings.Global.AUTO_TIME_ZONE, 0); 4225 } 4226 4227 @Test testIsOrganizationOwnedDevice()4228 public void testIsOrganizationOwnedDevice() throws Exception { 4229 // Set up the user manager to return correct user info 4230 addManagedProfile(admin1, DpmMockContext.CALLER_UID, admin1); 4231 4232 // Any caller should be able to call this method. 4233 assertThat(dpm.isOrganizationOwnedDeviceWithManagedProfile()).isFalse(); 4234 configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE); 4235 4236 verify(getServices().userManager).setUserRestriction( 4237 eq(UserManager.DISALLOW_ADD_USER), 4238 eq(true), 4239 eq(UserHandle.of(UserHandle.USER_SYSTEM))); 4240 4241 assertThat(dpm.isOrganizationOwnedDeviceWithManagedProfile()).isTrue(); 4242 4243 // A random caller from another user should also be able to get the right result. 4244 mContext.binder.callingUid = DpmMockContext.ANOTHER_UID; 4245 assertThat(dpm.isOrganizationOwnedDeviceWithManagedProfile()).isTrue(); 4246 } 4247 4248 @Test testMarkOrganizationOwnedDevice_baseRestrictionsAdded()4249 public void testMarkOrganizationOwnedDevice_baseRestrictionsAdded() throws Exception { 4250 addManagedProfile(admin1, DpmMockContext.CALLER_UID, admin1); 4251 4252 configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE); 4253 4254 // Base restriction DISALLOW_REMOVE_MANAGED_PROFILE added 4255 verify(getServices().userManager).setUserRestriction( 4256 eq(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE), 4257 eq(true), 4258 eq(UserHandle.of(UserHandle.USER_SYSTEM))); 4259 4260 // Base restriction DISALLOW_ADD_USER added 4261 verify(getServices().userManager).setUserRestriction( 4262 eq(UserManager.DISALLOW_ADD_USER), 4263 eq(true), 4264 eq(UserHandle.of(UserHandle.USER_SYSTEM))); 4265 4266 // Assert base restrictions cannot be added or removed by admin 4267 assertExpectException(SecurityException.class, null, () -> 4268 parentDpm.addUserRestriction(admin1, UserManager.DISALLOW_REMOVE_MANAGED_PROFILE)); 4269 assertExpectException(SecurityException.class, null, () -> 4270 parentDpm.clearUserRestriction(admin1, 4271 UserManager.DISALLOW_REMOVE_MANAGED_PROFILE)); 4272 assertExpectException(SecurityException.class, null, () -> 4273 parentDpm.addUserRestriction(admin1, UserManager.DISALLOW_ADD_USER)); 4274 assertExpectException(SecurityException.class, null, () -> 4275 parentDpm.clearUserRestriction(admin1, UserManager.DISALLOW_ADD_USER)); 4276 } 4277 4278 @Test testSetTime()4279 public void testSetTime() throws Exception { 4280 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 4281 setupDeviceOwner(); 4282 dpm.setTime(admin1, 0); 4283 verify(getServices().alarmManager).setTime(0); 4284 } 4285 4286 @Test testSetTimeFailWithPO()4287 public void testSetTimeFailWithPO() throws Exception { 4288 setupProfileOwner(); 4289 assertExpectException(SecurityException.class, null, () -> dpm.setTime(admin1, 0)); 4290 } 4291 4292 @Test testSetTimeWithPOOfOrganizationOwnedDevice()4293 public void testSetTimeWithPOOfOrganizationOwnedDevice() throws Exception { 4294 setupProfileOwner(); 4295 configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE); 4296 dpm.setTime(admin1, 0); 4297 verify(getServices().alarmManager).setTime(0); 4298 } 4299 4300 @Test testSetTimeWithAutoTimeOn()4301 public void testSetTimeWithAutoTimeOn() throws Exception { 4302 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 4303 setupDeviceOwner(); 4304 when(getServices().settings.settingsGlobalGetInt(Settings.Global.AUTO_TIME, 0)) 4305 .thenReturn(1); 4306 assertThat(dpm.setTime(admin1, 0)).isFalse(); 4307 } 4308 4309 @Test testSetTimeZone()4310 public void testSetTimeZone() throws Exception { 4311 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 4312 setupDeviceOwner(); 4313 dpm.setTimeZone(admin1, "Asia/Shanghai"); 4314 verify(getServices().alarmManager).setTimeZone("Asia/Shanghai"); 4315 } 4316 4317 @Test testSetTimeZoneFailWithPO()4318 public void testSetTimeZoneFailWithPO() throws Exception { 4319 setupProfileOwner(); 4320 assertExpectException(SecurityException.class, null, 4321 () -> dpm.setTimeZone(admin1, "Asia/Shanghai")); 4322 } 4323 4324 @Test testSetTimeZoneWithPOOfOrganizationOwnedDevice()4325 public void testSetTimeZoneWithPOOfOrganizationOwnedDevice() throws Exception { 4326 setupProfileOwner(); 4327 configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE); 4328 dpm.setTimeZone(admin1, "Asia/Shanghai"); 4329 verify(getServices().alarmManager).setTimeZone("Asia/Shanghai"); 4330 } 4331 4332 @Test testSetTimeZoneWithAutoTimeZoneOn()4333 public void testSetTimeZoneWithAutoTimeZoneOn() throws Exception { 4334 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 4335 setupDeviceOwner(); 4336 when(getServices().settings.settingsGlobalGetInt(Settings.Global.AUTO_TIME_ZONE, 0)) 4337 .thenReturn(1); 4338 assertThat(dpm.setTimeZone(admin1, "Asia/Shanghai")).isFalse(); 4339 } 4340 4341 @Test testGetLastBugReportRequestTime()4342 public void testGetLastBugReportRequestTime() throws Exception { 4343 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 4344 setupDeviceOwner(); 4345 4346 mContext.packageName = admin1.getPackageName(); 4347 mContext.applicationInfo = new ApplicationInfo(); 4348 when(mContext.resources.getColor(anyInt(), anyObject())).thenReturn(Color.WHITE); 4349 4350 // setUp() adds a secondary user for CALLER_USER_HANDLE. Remove it as otherwise the 4351 // feature is disabled because there are non-affiliated secondary users. 4352 getServices().removeUser(CALLER_USER_HANDLE); 4353 4354 // No bug reports were requested so far. 4355 assertThat(dpm.getLastBugReportRequestTime()).isEqualTo(-1); 4356 4357 // Requesting a bug report should update the timestamp. 4358 final long beforeRequest = System.currentTimeMillis(); 4359 dpm.requestBugreport(admin1); 4360 final long bugReportRequestTime = dpm.getLastBugReportRequestTime(); 4361 final long afterRequest = System.currentTimeMillis(); 4362 assertThat(bugReportRequestTime).isAtLeast(beforeRequest); 4363 assertThat(bugReportRequestTime).isAtMost(afterRequest); 4364 4365 // Checking the timestamp again should not change it. 4366 Thread.sleep(2); 4367 assertThat(dpm.getLastBugReportRequestTime()).isEqualTo(bugReportRequestTime); 4368 4369 // Restarting the DPMS should not lose the timestamp. 4370 initializeDpms(); 4371 assertThat(dpm.getLastBugReportRequestTime()).isEqualTo(bugReportRequestTime); 4372 4373 // Any uid holding MANAGE_USERS permission can retrieve the timestamp. 4374 mContext.binder.callingUid = 1234567; 4375 mContext.callerPermissions.add(permission.MANAGE_USERS); 4376 assertThat(dpm.getLastBugReportRequestTime()).isEqualTo(bugReportRequestTime); 4377 mContext.callerPermissions.remove(permission.MANAGE_USERS); 4378 4379 // System can retrieve the timestamp. 4380 mContext.binder.clearCallingIdentity(); 4381 assertThat(dpm.getLastBugReportRequestTime()).isEqualTo(bugReportRequestTime); 4382 4383 // Removing the device owner should clear the timestamp. 4384 clearDeviceOwner(); 4385 assertThat(dpm.getLastBugReportRequestTime()).isEqualTo(-1); 4386 } 4387 4388 @Test testGetLastNetworkLogRetrievalTime()4389 public void testGetLastNetworkLogRetrievalTime() throws Exception { 4390 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 4391 setupDeviceOwner(); 4392 mContext.packageName = admin1.getPackageName(); 4393 mContext.applicationInfo = new ApplicationInfo(); 4394 when(mContext.resources.getColor(anyInt(), anyObject())).thenReturn(Color.WHITE); 4395 4396 // setUp() adds a secondary user for CALLER_USER_HANDLE. Remove it as otherwise the 4397 // feature is disabled because there are non-affiliated secondary users. 4398 getServices().removeUser(CALLER_USER_HANDLE); 4399 when(getServices().iipConnectivityMetrics.addNetdEventCallback(anyInt(), anyObject())) 4400 .thenReturn(true); 4401 4402 // No logs were retrieved so far. 4403 assertThat(dpm.getLastNetworkLogRetrievalTime()).isEqualTo(-1); 4404 4405 // Attempting to retrieve logs without enabling logging should not change the timestamp. 4406 dpm.retrieveNetworkLogs(admin1, 0 /* batchToken */); 4407 assertThat(dpm.getLastNetworkLogRetrievalTime()).isEqualTo(-1); 4408 4409 // Enabling logging should not change the timestamp. 4410 dpm.setNetworkLoggingEnabled(admin1, true); 4411 assertThat(dpm.getLastNetworkLogRetrievalTime()).isEqualTo(-1); 4412 4413 // Retrieving the logs should update the timestamp. 4414 final long beforeRetrieval = System.currentTimeMillis(); 4415 dpm.retrieveNetworkLogs(admin1, 0 /* batchToken */); 4416 final long firstNetworkLogRetrievalTime = dpm.getLastNetworkLogRetrievalTime(); 4417 final long afterRetrieval = System.currentTimeMillis(); 4418 assertThat(firstNetworkLogRetrievalTime >= beforeRetrieval).isTrue(); 4419 assertThat(firstNetworkLogRetrievalTime <= afterRetrieval).isTrue(); 4420 4421 // Checking the timestamp again should not change it. 4422 Thread.sleep(2); 4423 assertThat(dpm.getLastNetworkLogRetrievalTime()).isEqualTo(firstNetworkLogRetrievalTime); 4424 4425 // Retrieving the logs again should update the timestamp. 4426 dpm.retrieveNetworkLogs(admin1, 0 /* batchToken */); 4427 final long secondNetworkLogRetrievalTime = dpm.getLastNetworkLogRetrievalTime(); 4428 assertThat(secondNetworkLogRetrievalTime > firstNetworkLogRetrievalTime).isTrue(); 4429 4430 // Disabling logging should not change the timestamp. 4431 Thread.sleep(2); 4432 dpm.setNetworkLoggingEnabled(admin1, false); 4433 assertThat(dpm.getLastNetworkLogRetrievalTime()).isEqualTo(secondNetworkLogRetrievalTime); 4434 4435 // Restarting the DPMS should not lose the timestamp. 4436 initializeDpms(); 4437 assertThat(dpm.getLastNetworkLogRetrievalTime()).isEqualTo(secondNetworkLogRetrievalTime); 4438 4439 // Any uid holding MANAGE_USERS permission can retrieve the timestamp. 4440 mContext.binder.callingUid = 1234567; 4441 mContext.callerPermissions.add(permission.MANAGE_USERS); 4442 assertThat(dpm.getLastNetworkLogRetrievalTime()).isEqualTo(secondNetworkLogRetrievalTime); 4443 mContext.callerPermissions.remove(permission.MANAGE_USERS); 4444 4445 // System can retrieve the timestamp. 4446 mContext.binder.clearCallingIdentity(); 4447 assertThat(dpm.getLastNetworkLogRetrievalTime()).isEqualTo(secondNetworkLogRetrievalTime); 4448 4449 // Removing the device owner should clear the timestamp. 4450 clearDeviceOwner(); 4451 assertThat(dpm.getLastNetworkLogRetrievalTime()).isEqualTo(-1); 4452 } 4453 4454 @Test testSetNetworkLoggingEnabled_asPo()4455 public void testSetNetworkLoggingEnabled_asPo() throws Exception { 4456 final int managedProfileUserId = CALLER_USER_HANDLE; 4457 final int managedProfileAdminUid = 4458 UserHandle.getUid(managedProfileUserId, DpmMockContext.SYSTEM_UID); 4459 mContext.binder.callingUid = managedProfileAdminUid; 4460 mContext.applicationInfo = new ApplicationInfo(); 4461 mContext.packageName = admin1.getPackageName(); 4462 addManagedProfile(admin1, managedProfileAdminUid, admin1, VERSION_CODES.S); 4463 when(getServices().iipConnectivityMetrics 4464 .addNetdEventCallback(anyInt(), anyObject())).thenReturn(true); 4465 4466 // Check no logs have been retrieved so far. 4467 assertThat(dpm.getLastNetworkLogRetrievalTime()).isEqualTo(-1); 4468 4469 // Enable network logging 4470 dpm.setNetworkLoggingEnabled(admin1, true); 4471 assertThat(dpm.getLastNetworkLogRetrievalTime()).isEqualTo(-1); 4472 4473 // Retrieve the network logs and verify timestamp has been updated. 4474 final long beforeRetrieval = System.currentTimeMillis(); 4475 4476 dpm.retrieveNetworkLogs(admin1, 0 /* batchToken */); 4477 4478 final long networkLogRetrievalTime = dpm.getLastNetworkLogRetrievalTime(); 4479 final long afterRetrieval = System.currentTimeMillis(); 4480 assertThat(networkLogRetrievalTime >= beforeRetrieval).isTrue(); 4481 assertThat(networkLogRetrievalTime <= afterRetrieval).isTrue(); 4482 } 4483 4484 @Test testSetNetworkLoggingEnabled_asPoOfOrgOwnedDevice()4485 public void testSetNetworkLoggingEnabled_asPoOfOrgOwnedDevice() throws Exception { 4486 // Setup profile owner on organization-owned device 4487 final int MANAGED_PROFILE_ADMIN_UID = 4488 UserHandle.getUid(CALLER_USER_HANDLE, DpmMockContext.SYSTEM_UID); 4489 addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1); 4490 configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE); 4491 4492 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 4493 mContext.packageName = admin1.getPackageName(); 4494 mContext.applicationInfo = new ApplicationInfo(); 4495 when(getServices().iipConnectivityMetrics 4496 .addNetdEventCallback(anyInt(), anyObject())).thenReturn(true); 4497 4498 // Check no logs have been retrieved so far. 4499 assertThat(dpm.getLastNetworkLogRetrievalTime()).isEqualTo(-1); 4500 4501 // Enable network logging 4502 dpm.setNetworkLoggingEnabled(admin1, true); 4503 assertThat(dpm.getLastNetworkLogRetrievalTime()).isEqualTo(-1); 4504 4505 // Retrieve the network logs and verify timestamp has been updated. 4506 final long beforeRetrieval = System.currentTimeMillis(); 4507 4508 dpm.retrieveNetworkLogs(admin1, 0 /* batchToken */); 4509 4510 final long networkLogRetrievalTime = dpm.getLastNetworkLogRetrievalTime(); 4511 final long afterRetrieval = System.currentTimeMillis(); 4512 assertThat(networkLogRetrievalTime >= beforeRetrieval).isTrue(); 4513 assertThat(networkLogRetrievalTime <= afterRetrieval).isTrue(); 4514 } 4515 4516 @Test testGetBindDeviceAdminTargetUsers()4517 public void testGetBindDeviceAdminTargetUsers() throws Exception { 4518 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS); 4519 4520 // Setup device owner. 4521 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 4522 setupDeviceOwner(); 4523 4524 // Only device owner is setup, the result list should be empty. 4525 List<UserHandle> targetUsers = dpm.getBindDeviceAdminTargetUsers(admin1); 4526 MoreAsserts.assertEmpty(targetUsers); 4527 4528 // Add a secondary user, it should never talk with. 4529 final int ANOTHER_USER_ID = 36; 4530 getServices().addUser(ANOTHER_USER_ID, 0, UserManager.USER_TYPE_FULL_SECONDARY); 4531 4532 // Since the managed profile is not affiliated, they should not be allowed to talk to each 4533 // other. 4534 targetUsers = dpm.getBindDeviceAdminTargetUsers(admin1); 4535 MoreAsserts.assertEmpty(targetUsers); 4536 4537 // Setting affiliation ids 4538 final Set<String> userAffiliationIds = Collections.singleton("some.affiliation-id"); 4539 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 4540 dpm.setAffiliationIds(admin1, userAffiliationIds); 4541 4542 // Changing affiliation ids in one 4543 dpm.setAffiliationIds(admin1, Collections.singleton("some-different-affiliation-id")); 4544 4545 // Since the managed profile is not affiliated any more, they should not be allowed to talk 4546 // to each other. 4547 targetUsers = dpm.getBindDeviceAdminTargetUsers(admin1); 4548 MoreAsserts.assertEmpty(targetUsers); 4549 4550 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 4551 targetUsers = dpm.getBindDeviceAdminTargetUsers(admin1); 4552 MoreAsserts.assertEmpty(targetUsers); 4553 } 4554 verifyLockTaskState(int userId)4555 private void verifyLockTaskState(int userId) throws Exception { 4556 verifyLockTaskState(userId, new String[0], 4557 DevicePolicyManager.LOCK_TASK_FEATURE_GLOBAL_ACTIONS); 4558 } 4559 verifyLockTaskState(int userId, String[] packages, int flags)4560 private void verifyLockTaskState(int userId, String[] packages, int flags) throws Exception { 4561 verify(getServices().iactivityManager).updateLockTaskPackages(userId, packages); 4562 verify(getServices().iactivityTaskManager).updateLockTaskFeatures(userId, flags); 4563 } 4564 verifyCanSetLockTask(int uid, int userId, ComponentName who, String[] packages, int flags)4565 private void verifyCanSetLockTask(int uid, int userId, ComponentName who, String[] packages, 4566 int flags) throws Exception { 4567 mContext.binder.callingUid = uid; 4568 dpm.setLockTaskPackages(who, packages); 4569 MoreAsserts.assertEquals(packages, dpm.getLockTaskPackages(who)); 4570 for (String p : packages) { 4571 assertThat(dpm.isLockTaskPermitted(p)).isTrue(); 4572 } 4573 assertThat(dpm.isLockTaskPermitted("anotherPackage")).isFalse(); 4574 // Test to see if set lock task features can be set 4575 dpm.setLockTaskFeatures(who, flags); 4576 verifyLockTaskState(userId, packages, flags); 4577 } 4578 verifyCanNotSetLockTask(int uid, ComponentName who, String[] packages, int flags)4579 private void verifyCanNotSetLockTask(int uid, ComponentName who, String[] packages, 4580 int flags) throws Exception { 4581 mContext.binder.callingUid = uid; 4582 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 4583 () -> dpm.setLockTaskPackages(who, packages)); 4584 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 4585 () -> dpm.getLockTaskPackages(who)); 4586 assertThat(dpm.isLockTaskPermitted("doPackage1")).isFalse(); 4587 assertExpectException(SecurityException.class, /* messageRegex =*/ null, 4588 () -> dpm.setLockTaskFeatures(who, flags)); 4589 } 4590 4591 @Test testLockTaskPolicyForProfileOwner()4592 public void testLockTaskPolicyForProfileOwner() throws Exception { 4593 mockPolicyExemptApps(); 4594 mockVendorPolicyExemptApps(); 4595 4596 // Setup a PO 4597 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 4598 setAsProfileOwner(admin1); 4599 verifyLockTaskState(CALLER_USER_HANDLE); 4600 4601 final String[] poPackages = {"poPackage1", "poPackage2"}; 4602 final int poFlags = DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATIONS 4603 | DevicePolicyManager.LOCK_TASK_FEATURE_HOME 4604 | DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW; 4605 verifyCanSetLockTask(DpmMockContext.CALLER_UID, CALLER_USER_HANDLE, admin1, 4606 poPackages, poFlags); 4607 4608 // Set up a managed profile managed by different package (package name shouldn't matter) 4609 final int MANAGED_PROFILE_USER_ID = 15; 4610 final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 20456); 4611 final ComponentName adminDifferentPackage = 4612 new ComponentName("another.package", "whatever.class"); 4613 addManagedProfile(adminDifferentPackage, MANAGED_PROFILE_ADMIN_UID, admin2); 4614 verifyLockTaskState(MANAGED_PROFILE_USER_ID); 4615 4616 // Managed profile is unaffiliated - shouldn't be able to setLockTaskPackages. 4617 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 4618 final String[] mpoPackages = {"poPackage1", "poPackage2"}; 4619 final int mpoFlags = DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATIONS 4620 | DevicePolicyManager.LOCK_TASK_FEATURE_HOME 4621 | DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW; 4622 verifyCanNotSetLockTask(MANAGED_PROFILE_ADMIN_UID, adminDifferentPackage, mpoPackages, 4623 mpoFlags); 4624 } 4625 4626 @Test testLockTaskFeatures_IllegalArgumentException()4627 public void testLockTaskFeatures_IllegalArgumentException() throws Exception { 4628 // Setup a device owner. 4629 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 4630 setupDeviceOwner(); 4631 // Lock task policy is updated when loading user data. 4632 verifyLockTaskState(UserHandle.USER_SYSTEM); 4633 4634 final int flags = DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATIONS 4635 | DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW; 4636 assertExpectException(IllegalArgumentException.class, 4637 "Cannot use LOCK_TASK_FEATURE_OVERVIEW without LOCK_TASK_FEATURE_HOME", 4638 () -> dpm.setLockTaskFeatures(admin1, flags)); 4639 } 4640 4641 @Test testSecondaryLockscreen_profileOwner()4642 public void testSecondaryLockscreen_profileOwner() throws Exception { 4643 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 4644 4645 // Initial state is disabled. 4646 assertThat(dpm.isSecondaryLockscreenEnabled(UserHandle.of( 4647 CALLER_USER_HANDLE))).isFalse(); 4648 4649 // Profile owner can set enabled state. 4650 setAsProfileOwner(admin1); 4651 when(mServiceContext.resources 4652 .getString(R.string.config_defaultSupervisionProfileOwnerComponent)) 4653 .thenReturn(admin1.flattenToString()); 4654 dpm.setSecondaryLockscreenEnabled(admin1, true); 4655 assertThat(dpm.isSecondaryLockscreenEnabled(UserHandle.of( 4656 CALLER_USER_HANDLE))).isTrue(); 4657 4658 // Managed profile managed by different package is unaffiliated - cannot set enabled. 4659 final int managedProfileUserId = 15; 4660 final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 20456); 4661 final ComponentName adminDifferentPackage = 4662 new ComponentName("another.package", "whatever.class"); 4663 addManagedProfile(adminDifferentPackage, managedProfileAdminUid, admin2); 4664 mContext.binder.callingUid = managedProfileAdminUid; 4665 assertExpectException(SecurityException.class, /* messageRegex= */ null, 4666 () -> dpm.setSecondaryLockscreenEnabled(adminDifferentPackage, false)); 4667 } 4668 4669 @Test testSecondaryLockscreen_deviceOwner()4670 public void testSecondaryLockscreen_deviceOwner() throws Exception { 4671 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 4672 4673 // Initial state is disabled. 4674 assertThat(dpm.isSecondaryLockscreenEnabled(UserHandle.of(UserHandle.USER_SYSTEM))) 4675 .isFalse(); 4676 4677 // Device owners can set enabled state. 4678 setupDeviceOwner(); 4679 when(mServiceContext.resources 4680 .getString(R.string.config_defaultSupervisionProfileOwnerComponent)) 4681 .thenReturn(admin1.flattenToString()); 4682 dpm.setSecondaryLockscreenEnabled(admin1, true); 4683 assertThat(dpm.isSecondaryLockscreenEnabled(UserHandle.of(UserHandle.USER_SYSTEM))) 4684 .isTrue(); 4685 } 4686 4687 @Test testSecondaryLockscreen_nonOwner()4688 public void testSecondaryLockscreen_nonOwner() throws Exception { 4689 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 4690 4691 // Initial state is disabled. 4692 assertThat(dpm.isSecondaryLockscreenEnabled(UserHandle.of(CALLER_USER_HANDLE))).isFalse(); 4693 4694 // Non-DO/PO cannot set enabled state. 4695 when(mServiceContext.resources 4696 .getString(R.string.config_defaultSupervisionProfileOwnerComponent)) 4697 .thenReturn(admin1.flattenToString()); 4698 assertExpectException(SecurityException.class, /* messageRegex= */ null, 4699 () -> dpm.setSecondaryLockscreenEnabled(admin1, true)); 4700 assertThat(dpm.isSecondaryLockscreenEnabled(UserHandle.of(CALLER_USER_HANDLE))).isFalse(); 4701 } 4702 4703 @Test testSecondaryLockscreen_nonSupervisionApp()4704 public void testSecondaryLockscreen_nonSupervisionApp() throws Exception { 4705 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 4706 4707 // Ensure packages are *not* flagged as test_only. 4708 doReturn(new ApplicationInfo()).when(getServices().ipackageManager).getApplicationInfo( 4709 eq(admin1.getPackageName()), 4710 anyInt(), 4711 eq(CALLER_USER_HANDLE)); 4712 doReturn(new ApplicationInfo()).when(getServices().ipackageManager).getApplicationInfo( 4713 eq(admin2.getPackageName()), 4714 anyInt(), 4715 eq(CALLER_USER_HANDLE)); 4716 4717 // Initial state is disabled. 4718 assertThat(dpm.isSecondaryLockscreenEnabled(UserHandle.of(CALLER_USER_HANDLE))).isFalse(); 4719 4720 // Caller is Profile Owner, but no supervision app is configured. 4721 setAsProfileOwner(admin1); 4722 assertExpectException(SecurityException.class, "is not the default supervision component", 4723 () -> dpm.setSecondaryLockscreenEnabled(admin1, true)); 4724 assertThat(dpm.isSecondaryLockscreenEnabled(UserHandle.of(CALLER_USER_HANDLE))).isFalse(); 4725 4726 // Caller is Profile Owner, but is not the default configured supervision app. 4727 when(mServiceContext.resources 4728 .getString(R.string.config_defaultSupervisionProfileOwnerComponent)) 4729 .thenReturn(admin2.flattenToString()); 4730 assertExpectException(SecurityException.class, "is not the default supervision component", 4731 () -> dpm.setSecondaryLockscreenEnabled(admin1, true)); 4732 assertThat(dpm.isSecondaryLockscreenEnabled(UserHandle.of(CALLER_USER_HANDLE))).isFalse(); 4733 } 4734 4735 @Test testIsDeviceManaged()4736 public void testIsDeviceManaged() throws Exception { 4737 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 4738 setupDeviceOwner(); 4739 4740 // The device owner itself, any uid holding MANAGE_USERS permission and the system can 4741 // find out that the device has a device owner. 4742 assertThat(dpm.isDeviceManaged()).isTrue(); 4743 mContext.binder.callingUid = 1234567; 4744 mContext.callerPermissions.add(permission.MANAGE_USERS); 4745 assertThat(dpm.isDeviceManaged()).isTrue(); 4746 mContext.callerPermissions.remove(permission.MANAGE_USERS); 4747 mContext.binder.clearCallingIdentity(); 4748 assertThat(dpm.isDeviceManaged()).isTrue(); 4749 4750 clearDeviceOwner(); 4751 4752 // Any uid holding MANAGE_USERS permission and the system can find out that the device does 4753 // not have a device owner. 4754 mContext.binder.callingUid = 1234567; 4755 mContext.callerPermissions.add(permission.MANAGE_USERS); 4756 assertThat(dpm.isDeviceManaged()).isFalse(); 4757 mContext.callerPermissions.remove(permission.MANAGE_USERS); 4758 mContext.binder.clearCallingIdentity(); 4759 assertThat(dpm.isDeviceManaged()).isFalse(); 4760 } 4761 4762 @Test testDeviceOwnerOrganizationName()4763 public void testDeviceOwnerOrganizationName() throws Exception { 4764 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 4765 setupDeviceOwner(); 4766 4767 dpm.setOrganizationName(admin1, "organization"); 4768 4769 // Device owner can retrieve organization managing the device. 4770 assertThat(dpm.getDeviceOwnerOrganizationName()).isEqualTo("organization"); 4771 4772 // Any uid holding MANAGE_USERS permission can retrieve organization managing the device. 4773 mContext.binder.callingUid = 1234567; 4774 mContext.callerPermissions.add(permission.MANAGE_USERS); 4775 assertThat(dpm.getDeviceOwnerOrganizationName()).isEqualTo("organization"); 4776 mContext.callerPermissions.remove(permission.MANAGE_USERS); 4777 4778 // System can retrieve organization managing the device. 4779 mContext.binder.clearCallingIdentity(); 4780 assertThat(dpm.getDeviceOwnerOrganizationName()).isEqualTo("organization"); 4781 4782 // Removing the device owner clears the organization managing the device. 4783 clearDeviceOwner(); 4784 assertThat(dpm.getDeviceOwnerOrganizationName()).isNull(); 4785 } 4786 4787 @Test testWipeDataManagedProfile()4788 public void testWipeDataManagedProfile() throws Exception { 4789 final int MANAGED_PROFILE_USER_ID = 15; 4790 final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 19436); 4791 addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1); 4792 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 4793 mServiceContext.permissions.add(permission.INTERACT_ACROSS_USERS_FULL); 4794 4795 // Even if the caller is the managed profile, the current user is the user 0 4796 when(getServices().iactivityManager.getCurrentUser()) 4797 .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0)); 4798 // Get mock reason string since we throw an IAE with empty string input. 4799 when(mContext.getResources().getString(R.string.work_profile_deleted_description_dpm_wipe)) 4800 .thenReturn("Just a test string."); 4801 4802 dpm.wipeData(0); 4803 verify(getServices().userManagerInternal).removeUserEvenWhenDisallowed( 4804 MANAGED_PROFILE_USER_ID); 4805 } 4806 4807 @Test testWipeDataManagedProfileOnOrganizationOwnedDevice()4808 public void testWipeDataManagedProfileOnOrganizationOwnedDevice() throws Exception { 4809 setupProfileOwner(); 4810 configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE); 4811 4812 // Even if the caller is the managed profile, the current user is the user 0 4813 when(getServices().iactivityManager.getCurrentUser()) 4814 .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0)); 4815 // Get mock reason string since we throw an IAE with empty string input. 4816 when(mContext.getResources().getString(R.string.work_profile_deleted_description_dpm_wipe)) 4817 .thenReturn("Just a test string."); 4818 when(getServices().userManager.getProfileParent(CALLER_USER_HANDLE)) 4819 .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0)); 4820 when(getServices().userManager.getPrimaryUser()) 4821 .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0)); 4822 4823 // Set some device-wide policies: 4824 // Security logging 4825 when(getServices().settings.securityLogGetLoggingEnabledProperty()).thenReturn(true); 4826 // System update policy 4827 dpms.mOwners.setSystemUpdatePolicy(SystemUpdatePolicy.createAutomaticInstallPolicy()); 4828 // Make it look as if FRP agent is present. 4829 when(dpms.mMockInjector.getPersistentDataBlockManagerInternal().getAllowedUid()) 4830 .thenReturn(12345 /* some UID in user 0 */); 4831 // Make personal apps look suspended 4832 dpms.getUserData(UserHandle.USER_SYSTEM).mAppsSuspended = true; 4833 4834 clearInvocations(getServices().iwindowManager); 4835 4836 dpm.wipeData(0); 4837 verify(getServices().userManagerInternal).removeUserEvenWhenDisallowed(CALLER_USER_HANDLE); 4838 4839 // Make sure COPE restrictions are lifted: 4840 verify(getServices().userManager).setUserRestriction( 4841 UserManager.DISALLOW_REMOVE_MANAGED_PROFILE, false, UserHandle.SYSTEM); 4842 verify(getServices().userManager).setUserRestriction( 4843 UserManager.DISALLOW_ADD_USER, false, UserHandle.SYSTEM); 4844 4845 // Some device-wide policies are getting cleaned-up after the user is removed. 4846 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 4847 sendBroadcastWithUser(dpms, Intent.ACTION_USER_REMOVED, CALLER_USER_HANDLE); 4848 4849 // Screenlock info should be removed 4850 verify(getServices().lockPatternUtils).setDeviceOwnerInfo(null); 4851 // Wifi config lockdown should be lifted 4852 verify(getServices().settings).settingsGlobalPutInt( 4853 Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN, 0); 4854 // System update policy should be removed 4855 assertThat(dpms.mOwners.getSystemUpdatePolicy()).isNull(); 4856 // FRP agent should be notified 4857 verify(mContext.spiedContext, times(0)).sendBroadcastAsUser( 4858 MockUtils.checkIntentAction( 4859 DevicePolicyManager.ACTION_RESET_PROTECTION_POLICY_CHANGED), 4860 MockUtils.checkUserHandle(UserHandle.USER_SYSTEM)); 4861 // Refresh strong auth timeout and screen capture 4862 verify(getServices().lockSettingsInternal).refreshStrongAuthTimeout(UserHandle.USER_SYSTEM); 4863 verify(getServices().iwindowManager).refreshScreenCaptureDisabled(UserHandle.USER_SYSTEM); 4864 // Unsuspend personal apps 4865 verify(getServices().packageManagerInternal) 4866 .unsuspendForSuspendingPackage(PLATFORM_PACKAGE_NAME, UserHandle.USER_SYSTEM); 4867 } 4868 4869 @Test testWipeDataManagedProfileDisallowed()4870 public void testWipeDataManagedProfileDisallowed() throws Exception { 4871 final int MANAGED_PROFILE_USER_ID = 15; 4872 final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 19436); 4873 addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1); 4874 4875 // Even if the caller is the managed profile, the current user is the user 0 4876 when(getServices().iactivityManager.getCurrentUser()) 4877 .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0)); 4878 4879 when(getServices().userManager.getUserRestrictionSource( 4880 UserManager.DISALLOW_REMOVE_MANAGED_PROFILE, 4881 UserHandle.of(MANAGED_PROFILE_USER_ID))) 4882 .thenReturn(UserManager.RESTRICTION_SOURCE_SYSTEM); 4883 when(mContext.getResources().getString(R.string.work_profile_deleted_description_dpm_wipe)). 4884 thenReturn("Just a test string."); 4885 4886 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 4887 // The PO is not allowed to remove the profile if the user restriction was set on the 4888 // profile by the system 4889 assertExpectException(SecurityException.class, /* messageRegex= */ null, 4890 () -> dpm.wipeData(0)); 4891 } 4892 4893 @Test testWipeDataDeviceOwner()4894 public void testWipeDataDeviceOwner() throws Exception { 4895 setDeviceOwner(); 4896 when(getServices().userManager.getUserRestrictionSource( 4897 UserManager.DISALLOW_FACTORY_RESET, 4898 UserHandle.SYSTEM)) 4899 .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER); 4900 when(mContext.getResources().getString(R.string.work_profile_deleted_description_dpm_wipe)). 4901 thenReturn("Just a test string."); 4902 4903 dpm.wipeData(0); 4904 4905 verifyRebootWipeUserData(/* wipeEuicc= */ false); 4906 } 4907 4908 @Test testWipeEuiccDataEnabled()4909 public void testWipeEuiccDataEnabled() throws Exception { 4910 setDeviceOwner(); 4911 when(getServices().userManager.getUserRestrictionSource( 4912 UserManager.DISALLOW_FACTORY_RESET, 4913 UserHandle.SYSTEM)) 4914 .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER); 4915 when(mContext.getResources().getString(R.string.work_profile_deleted_description_dpm_wipe)). 4916 thenReturn("Just a test string."); 4917 4918 dpm.wipeData(WIPE_EUICC); 4919 4920 verifyRebootWipeUserData(/* wipeEuicc= */ true); 4921 } 4922 4923 @Test testWipeDataDeviceOwnerDisallowed()4924 public void testWipeDataDeviceOwnerDisallowed() throws Exception { 4925 setDeviceOwner(); 4926 when(getServices().userManager.getUserRestrictionSource( 4927 UserManager.DISALLOW_FACTORY_RESET, 4928 UserHandle.SYSTEM)) 4929 .thenReturn(UserManager.RESTRICTION_SOURCE_SYSTEM); 4930 when(mContext.getResources().getString(R.string.work_profile_deleted_description_dpm_wipe)). 4931 thenReturn("Just a test string."); 4932 // The DO is not allowed to wipe the device if the user restriction was set 4933 // by the system 4934 assertExpectException(SecurityException.class, /* messageRegex= */ null, 4935 () -> dpm.wipeData(0)); 4936 } 4937 4938 @Test testMaximumFailedPasswordAttemptsReachedManagedProfile()4939 public void testMaximumFailedPasswordAttemptsReachedManagedProfile() throws Exception { 4940 final int MANAGED_PROFILE_USER_ID = 15; 4941 final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 19436); 4942 addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1); 4943 4944 // Even if the caller is the managed profile, the current user is the user 0 4945 when(getServices().iactivityManager.getCurrentUser()) 4946 .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0)); 4947 4948 when(getServices().userManager.getUserRestrictionSource( 4949 UserManager.DISALLOW_REMOVE_MANAGED_PROFILE, 4950 UserHandle.of(MANAGED_PROFILE_USER_ID))) 4951 .thenReturn(UserManager.RESTRICTION_SOURCE_PROFILE_OWNER); 4952 4953 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 4954 dpm.setMaximumFailedPasswordsForWipe(admin1, 3); 4955 4956 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 4957 mContext.callerPermissions.add(permission.BIND_DEVICE_ADMIN); 4958 // Failed password attempts on the parent user are taken into account, as there isn't a 4959 // separate work challenge. 4960 dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM); 4961 dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM); 4962 dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM); 4963 4964 // The profile should be wiped even if DISALLOW_REMOVE_MANAGED_PROFILE is enabled, because 4965 // both the user restriction and the policy were set by the PO. 4966 verify(getServices().userManagerInternal).removeUserEvenWhenDisallowed( 4967 MANAGED_PROFILE_USER_ID); 4968 verifyZeroInteractions(getServices().recoverySystem); 4969 } 4970 4971 @Test testMaximumFailedPasswordAttemptsReachedManagedProfileDisallowed()4972 public void testMaximumFailedPasswordAttemptsReachedManagedProfileDisallowed() 4973 throws Exception { 4974 final int MANAGED_PROFILE_USER_ID = 15; 4975 final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 19436); 4976 addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1); 4977 4978 // Even if the caller is the managed profile, the current user is the user 0 4979 when(getServices().iactivityManager.getCurrentUser()) 4980 .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0)); 4981 4982 when(getServices().userManager.getUserRestrictionSource( 4983 UserManager.DISALLOW_REMOVE_MANAGED_PROFILE, 4984 UserHandle.of(MANAGED_PROFILE_USER_ID))) 4985 .thenReturn(UserManager.RESTRICTION_SOURCE_SYSTEM); 4986 4987 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 4988 dpm.setMaximumFailedPasswordsForWipe(admin1, 3); 4989 4990 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 4991 mContext.callerPermissions.add(permission.BIND_DEVICE_ADMIN); 4992 // Failed password attempts on the parent user are taken into account, as there isn't a 4993 // separate work challenge. 4994 dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM); 4995 dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM); 4996 dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM); 4997 4998 // DISALLOW_REMOVE_MANAGED_PROFILE was set by the system, not the PO, so the profile is 4999 // not wiped. 5000 verify(getServices().userManagerInternal, never()) 5001 .removeUserEvenWhenDisallowed(anyInt()); 5002 verifyZeroInteractions(getServices().recoverySystem); 5003 } 5004 5005 @Test testMaximumFailedPasswordAttemptsReachedDeviceOwner()5006 public void testMaximumFailedPasswordAttemptsReachedDeviceOwner() throws Exception { 5007 setDeviceOwner(); 5008 when(getServices().userManager.getUserRestrictionSource( 5009 UserManager.DISALLOW_FACTORY_RESET, 5010 UserHandle.SYSTEM)) 5011 .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER); 5012 5013 dpm.setMaximumFailedPasswordsForWipe(admin1, 3); 5014 5015 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 5016 mContext.callerPermissions.add(permission.BIND_DEVICE_ADMIN); 5017 dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM); 5018 dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM); 5019 dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM); 5020 5021 // The device should be wiped even if DISALLOW_FACTORY_RESET is enabled, because both the 5022 // user restriction and the policy were set by the DO. 5023 verifyRebootWipeUserData(/* wipeEuicc= */ false); 5024 } 5025 5026 @Test testMaximumFailedPasswordAttemptsReachedDeviceOwnerDisallowed()5027 public void testMaximumFailedPasswordAttemptsReachedDeviceOwnerDisallowed() throws Exception { 5028 setDeviceOwner(); 5029 when(getServices().userManager.getUserRestrictionSource( 5030 UserManager.DISALLOW_FACTORY_RESET, 5031 UserHandle.SYSTEM)) 5032 .thenReturn(UserManager.RESTRICTION_SOURCE_SYSTEM); 5033 5034 dpm.setMaximumFailedPasswordsForWipe(admin1, 3); 5035 5036 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 5037 mContext.callerPermissions.add(permission.BIND_DEVICE_ADMIN); 5038 dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM); 5039 dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM); 5040 dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM); 5041 5042 // DISALLOW_FACTORY_RESET was set by the system, not the DO, so the device is not wiped. 5043 verifyZeroInteractions(getServices().recoverySystem); 5044 verify(getServices().userManagerInternal, never()) 5045 .removeUserEvenWhenDisallowed(anyInt()); 5046 } 5047 5048 @Test testMaximumFailedDevicePasswordAttemptsReachedOrgOwnedManagedProfile()5049 public void testMaximumFailedDevicePasswordAttemptsReachedOrgOwnedManagedProfile() 5050 throws Exception { 5051 final int MANAGED_PROFILE_USER_ID = 15; 5052 final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 19436); 5053 addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1); 5054 5055 // Even if the caller is the managed profile, the current user is the user 0 5056 when(getServices().iactivityManager.getCurrentUser()) 5057 .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0)); 5058 5059 configureProfileOwnerOfOrgOwnedDevice(admin1, MANAGED_PROFILE_USER_ID); 5060 5061 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 5062 dpm.setMaximumFailedPasswordsForWipe(admin1, 3); 5063 5064 assertThat(dpm.getMaximumFailedPasswordsForWipe(admin1)).isEqualTo(3); 5065 assertThat(dpm.getMaximumFailedPasswordsForWipe(null)).isEqualTo(3); 5066 5067 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 5068 mContext.callerPermissions.add(permission.BIND_DEVICE_ADMIN); 5069 5070 assertThat(dpm.getMaximumFailedPasswordsForWipe(null, UserHandle.USER_SYSTEM)).isEqualTo(3); 5071 // Check that primary will be wiped as a result of failed primary user unlock attempts. 5072 assertThat(dpm.getProfileWithMinimumFailedPasswordsForWipe(UserHandle.USER_SYSTEM)) 5073 .isEqualTo(UserHandle.USER_SYSTEM); 5074 5075 // Failed password attempts on the parent user are taken into account, as there isn't a 5076 // separate work challenge. 5077 dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM); 5078 dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM); 5079 dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM); 5080 5081 // For managed profile on an organization owned device, the whole device should be wiped. 5082 verifyRebootWipeUserData(/* wipeEuicc= */ false); 5083 } 5084 5085 @Test testMaximumFailedProfilePasswordAttemptsReachedOrgOwnedManagedProfile()5086 public void testMaximumFailedProfilePasswordAttemptsReachedOrgOwnedManagedProfile() 5087 throws Exception { 5088 final int MANAGED_PROFILE_USER_ID = 15; 5089 final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 19436); 5090 addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1); 5091 5092 // Even if the caller is the managed profile, the current user is the user 0 5093 when(getServices().iactivityManager.getCurrentUser()) 5094 .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0)); 5095 5096 doReturn(true).when(getServices().lockPatternUtils) 5097 .isSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID); 5098 5099 // Configure separate challenge. 5100 configureProfileOwnerOfOrgOwnedDevice(admin1, MANAGED_PROFILE_USER_ID); 5101 5102 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 5103 dpm.setMaximumFailedPasswordsForWipe(admin1, 3); 5104 5105 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 5106 mContext.callerPermissions.add(permission.BIND_DEVICE_ADMIN); 5107 5108 assertThat(dpm.getMaximumFailedPasswordsForWipe(null, UserHandle.USER_SYSTEM)).isEqualTo(0); 5109 assertThat(dpm.getMaximumFailedPasswordsForWipe(null, MANAGED_PROFILE_USER_ID)) 5110 .isEqualTo(3); 5111 // Check that the policy is not affecting primary profile challenge. 5112 assertThat(dpm.getProfileWithMinimumFailedPasswordsForWipe(UserHandle.USER_SYSTEM)) 5113 .isEqualTo(UserHandle.USER_NULL); 5114 // Check that primary will be wiped as a result of failed profile unlock attempts. 5115 assertThat(dpm.getProfileWithMinimumFailedPasswordsForWipe(MANAGED_PROFILE_USER_ID)) 5116 .isEqualTo(UserHandle.USER_SYSTEM); 5117 5118 // Simulate three failed attempts at solving the separate challenge. 5119 dpm.reportFailedPasswordAttempt(MANAGED_PROFILE_USER_ID); 5120 dpm.reportFailedPasswordAttempt(MANAGED_PROFILE_USER_ID); 5121 dpm.reportFailedPasswordAttempt(MANAGED_PROFILE_USER_ID); 5122 5123 // For managed profile on an organization owned device, the whole device should be wiped. 5124 verifyRebootWipeUserData(/* wipeEuicc= */ false); 5125 } 5126 5127 @Test testGetPermissionGrantState()5128 public void testGetPermissionGrantState() throws Exception { 5129 final String permission = "some.permission"; 5130 final String app1 = "com.example.app1"; 5131 final String app2 = "com.example.app2"; 5132 5133 when(getServices().ipackageManager.checkPermission(eq(permission), eq(app1), anyInt())) 5134 .thenReturn(PackageManager.PERMISSION_GRANTED); 5135 doReturn(PackageManager.FLAG_PERMISSION_POLICY_FIXED).when(getServices().packageManager) 5136 .getPermissionFlags(permission, app1, UserHandle.SYSTEM); 5137 when(getServices().packageManager.getPermissionFlags(permission, app1, 5138 UserHandle.of(CALLER_USER_HANDLE))) 5139 .thenReturn(PackageManager.FLAG_PERMISSION_POLICY_FIXED); 5140 when(getServices().ipackageManager.checkPermission(eq(permission), eq(app2), anyInt())) 5141 .thenReturn(PackageManager.PERMISSION_DENIED); 5142 doReturn(0).when(getServices().packageManager).getPermissionFlags(permission, app2, 5143 UserHandle.SYSTEM); 5144 when(getServices().packageManager.getPermissionFlags(permission, app2, 5145 UserHandle.of(CALLER_USER_HANDLE))).thenReturn(0); 5146 5147 // System can retrieve permission grant state. 5148 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 5149 mContext.packageName = "android"; 5150 assertThat(dpm.getPermissionGrantState(null, app1, permission)) 5151 .isEqualTo(DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED); 5152 assertThat(dpm.getPermissionGrantState(null, app2, permission)) 5153 .isEqualTo(DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT); 5154 5155 // A regular app cannot retrieve permission grant state. 5156 mContext.binder.callingUid = setupPackageInPackageManager(app1, 1); 5157 mContext.packageName = app1; 5158 assertExpectException(SecurityException.class, /* messageRegex= */ null, 5159 () -> dpm.getPermissionGrantState(null, app1, permission)); 5160 5161 // Profile owner can retrieve permission grant state. 5162 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 5163 mContext.packageName = admin1.getPackageName(); 5164 setAsProfileOwner(admin1); 5165 assertThat(dpm.getPermissionGrantState(admin1, app1, permission)) 5166 .isEqualTo(DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED); 5167 assertThat(dpm.getPermissionGrantState(admin1, app2, permission)) 5168 .isEqualTo(DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT); 5169 } 5170 5171 @Test testResetPasswordWithToken()5172 public void testResetPasswordWithToken() throws Exception { 5173 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 5174 setupDeviceOwner(); 5175 // test token validation 5176 assertExpectException(IllegalArgumentException.class, /* messageRegex= */ null, 5177 () -> dpm.setResetPasswordToken(admin1, new byte[31])); 5178 5179 // test adding a token 5180 final byte[] token = new byte[32]; 5181 final long handle = 123456; 5182 final String password = "password"; 5183 when(getServices().lockPatternUtils.addEscrowToken(eq(token), eq(UserHandle.USER_SYSTEM), 5184 nullable(EscrowTokenStateChangeCallback.class))) 5185 .thenReturn(handle); 5186 assertThat(dpm.setResetPasswordToken(admin1, token)).isTrue(); 5187 5188 // test password activation 5189 when(getServices().lockPatternUtils.isEscrowTokenActive(handle, UserHandle.USER_SYSTEM)) 5190 .thenReturn(true); 5191 assertThat(dpm.isResetPasswordTokenActive(admin1)).isTrue(); 5192 5193 // test reset password with token 5194 when(getServices().lockPatternUtils.setLockCredentialWithToken( 5195 LockscreenCredential.createPassword(password), handle, token, 5196 UserHandle.USER_SYSTEM)).thenReturn(true); 5197 assertThat(dpm.resetPasswordWithToken(admin1, password, token, 0)).isTrue(); 5198 5199 // test removing a token 5200 when(getServices().lockPatternUtils.removeEscrowToken(handle, UserHandle.USER_SYSTEM)) 5201 .thenReturn(true); 5202 assertThat(dpm.clearResetPasswordToken(admin1)).isTrue(); 5203 } 5204 5205 @Test resetPasswordWithToken_NumericPin()5206 public void resetPasswordWithToken_NumericPin() throws Exception { 5207 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 5208 setupDeviceOwner(); 5209 // adding a token 5210 final byte[] token = new byte[32]; 5211 final long handle = 123456; 5212 when(getServices().lockPatternUtils.addEscrowToken(eq(token), eq(UserHandle.USER_SYSTEM), 5213 nullable(EscrowTokenStateChangeCallback.class))) 5214 .thenReturn(handle); 5215 assertThat(dpm.setResetPasswordToken(admin1, token)).isTrue(); 5216 5217 // Test resetting with a numeric pin 5218 final String pin = "123456"; 5219 when(getServices().lockPatternUtils.setLockCredentialWithToken( 5220 LockscreenCredential.createPin(pin), handle, token, 5221 UserHandle.USER_SYSTEM)).thenReturn(true); 5222 assertThat(dpm.resetPasswordWithToken(admin1, pin, token, 0)).isTrue(); 5223 } 5224 5225 @Test resetPasswordWithToken_EmptyPassword()5226 public void resetPasswordWithToken_EmptyPassword() throws Exception { 5227 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 5228 setupDeviceOwner(); 5229 // adding a token 5230 final byte[] token = new byte[32]; 5231 final long handle = 123456; 5232 when(getServices().lockPatternUtils.addEscrowToken(eq(token), eq(UserHandle.USER_SYSTEM), 5233 nullable(EscrowTokenStateChangeCallback.class))) 5234 .thenReturn(handle); 5235 assertThat(dpm.setResetPasswordToken(admin1, token)).isTrue(); 5236 5237 // Test resetting with an empty password 5238 final String password = ""; 5239 when(getServices().lockPatternUtils.setLockCredentialWithToken( 5240 LockscreenCredential.createNone(), handle, token, 5241 UserHandle.USER_SYSTEM)).thenReturn(true); 5242 assertThat(dpm.resetPasswordWithToken(admin1, password, token, 0)).isTrue(); 5243 } 5244 5245 @Test testIsActivePasswordSufficient()5246 public void testIsActivePasswordSufficient() throws Exception { 5247 assumeDeprecatedPasswordApisSupported(); 5248 5249 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 5250 mContext.packageName = admin1.getPackageName(); 5251 setupDeviceOwner(); 5252 5253 dpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_COMPLEX); 5254 dpm.setPasswordMinimumLength(admin1, 8); 5255 dpm.setPasswordMinimumLetters(admin1, 6); 5256 dpm.setPasswordMinimumLowerCase(admin1, 3); 5257 dpm.setPasswordMinimumUpperCase(admin1, 1); 5258 dpm.setPasswordMinimumNonLetter(admin1, 1); 5259 dpm.setPasswordMinimumNumeric(admin1, 1); 5260 dpm.setPasswordMinimumSymbols(admin1, 0); 5261 5262 reset(mContext.spiedContext); 5263 5264 PasswordMetrics passwordMetricsNoSymbols = computeForPasswordOrPin( 5265 "abcdXYZ5".getBytes(), /* isPin */ false); 5266 5267 setActivePasswordState(passwordMetricsNoSymbols); 5268 assertThat(dpm.isActivePasswordSufficient()).isTrue(); 5269 5270 initializeDpms(); 5271 reset(mContext.spiedContext); 5272 assertThat(dpm.isActivePasswordSufficient()).isTrue(); 5273 5274 // This call simulates the user entering the password for the first time after a reboot. 5275 // This causes password metrics to be reloaded into memory. Until this happens, 5276 // dpm.isActivePasswordSufficient() will continue to return its last checkpointed value, 5277 // even if the DPC changes password requirements so that the password no longer meets the 5278 // requirements. This is a known limitation of the current implementation of 5279 // isActivePasswordSufficient() - see b/34218769. 5280 setActivePasswordState(passwordMetricsNoSymbols); 5281 assertThat(dpm.isActivePasswordSufficient()).isTrue(); 5282 5283 dpm.setPasswordMinimumSymbols(admin1, 1); 5284 // This assertion would fail if we had not called setActivePasswordState() again after 5285 // initializeDpms() - see previous comment. 5286 assertThat(dpm.isActivePasswordSufficient()).isFalse(); 5287 5288 initializeDpms(); 5289 reset(mContext.spiedContext); 5290 assertThat(dpm.isActivePasswordSufficient()).isFalse(); 5291 5292 PasswordMetrics passwordMetricsWithSymbols = computeForPasswordOrPin( 5293 "abcd.XY5".getBytes(), /* isPin */ false); 5294 5295 setActivePasswordState(passwordMetricsWithSymbols); 5296 assertThat(dpm.isActivePasswordSufficient()).isTrue(); 5297 } 5298 5299 @Test testIsActivePasswordSufficient_noLockScreen()5300 public void testIsActivePasswordSufficient_noLockScreen() throws Exception { 5301 assumeDeprecatedPasswordApisSupported(); 5302 5303 // If there is no lock screen, the password is considered empty no matter what, because 5304 // it provides no security. 5305 when(getServices().lockPatternUtils.hasSecureLockScreen()).thenReturn(false); 5306 5307 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 5308 mContext.packageName = admin1.getPackageName(); 5309 setupDeviceOwner(); 5310 final int userHandle = UserHandle.getUserId(mContext.binder.callingUid); 5311 // When there is no lockscreen, user password metrics is always empty. 5312 when(getServices().lockSettingsInternal.getUserPasswordMetrics(userHandle)) 5313 .thenReturn(new PasswordMetrics(CREDENTIAL_TYPE_NONE)); 5314 5315 // If no password requirements are set, isActivePasswordSufficient should succeed. 5316 assertThat(dpm.isActivePasswordSufficient()).isTrue(); 5317 5318 // Now set some password quality requirements. 5319 dpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING); 5320 5321 reset(mContext.spiedContext); 5322 // This should be ignored, as there is no lock screen. 5323 dpm.reportPasswordChanged(userHandle); 5324 5325 // No broadcast should be sent. 5326 verify(mContext.spiedContext, times(0)).sendBroadcastAsUser( 5327 MockUtils.checkIntentAction(DeviceAdminReceiver.ACTION_PASSWORD_CHANGED), 5328 MockUtils.checkUserHandle(userHandle)); 5329 5330 // The active (nonexistent) password doesn't comply with the requirements. 5331 assertThat(dpm.isActivePasswordSufficient()).isFalse(); 5332 } 5333 5334 @Test testIsPasswordSufficientAfterProfileUnification()5335 public void testIsPasswordSufficientAfterProfileUnification() throws Exception { 5336 final int managedProfileUserId = CALLER_USER_HANDLE; 5337 final int managedProfileAdminUid = 5338 UserHandle.getUid(managedProfileUserId, DpmMockContext.SYSTEM_UID); 5339 mContext.binder.callingUid = managedProfileAdminUid; 5340 5341 addManagedProfile(admin1, managedProfileAdminUid, admin1); 5342 doReturn(true).when(getServices().lockPatternUtils) 5343 .isSeparateProfileChallengeEnabled(managedProfileUserId); 5344 5345 dpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_HIGH); 5346 parentDpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_MEDIUM); 5347 5348 when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM)) 5349 .thenReturn(computeForPasswordOrPin("184342".getBytes(), /* isPin */ true)); 5350 5351 // Numeric password is compliant with current requirement (QUALITY_NUMERIC set explicitly 5352 // on the parent admin) 5353 assertThat(dpm.isPasswordSufficientAfterProfileUnification(UserHandle.USER_SYSTEM, 5354 UserHandle.USER_NULL)).isTrue(); 5355 // Numeric password is not compliant if profile is to be unified: the profile has a 5356 // QUALITY_ALPHABETIC policy on itself which will be enforced on the password after 5357 // unification. 5358 assertThat(dpm.isPasswordSufficientAfterProfileUnification(UserHandle.USER_SYSTEM, 5359 managedProfileUserId)).isFalse(); 5360 } 5361 5362 @Test testGetAggregatedPasswordComplexity_IgnoreProfileRequirement()5363 public void testGetAggregatedPasswordComplexity_IgnoreProfileRequirement() 5364 throws Exception { 5365 final int managedProfileUserId = CALLER_USER_HANDLE; 5366 final int managedProfileAdminUid = 5367 UserHandle.getUid(managedProfileUserId, DpmMockContext.SYSTEM_UID); 5368 mContext.binder.callingUid = managedProfileAdminUid; 5369 addManagedProfile(admin1, managedProfileAdminUid, admin1, VERSION_CODES.R); 5370 5371 dpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_HIGH); 5372 parentDpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_LOW); 5373 5374 assertThat(dpms.getAggregatedPasswordComplexityForUser(UserHandle.USER_SYSTEM, true)) 5375 .isEqualTo(PASSWORD_COMPLEXITY_LOW); 5376 assertThat(dpms.getAggregatedPasswordComplexityForUser(UserHandle.USER_SYSTEM, false)) 5377 .isEqualTo(PASSWORD_COMPLEXITY_HIGH); 5378 } 5379 5380 @Test testGetAggregatedPasswordMetrics_IgnoreProfileRequirement()5381 public void testGetAggregatedPasswordMetrics_IgnoreProfileRequirement() 5382 throws Exception { 5383 assumeDeprecatedPasswordApisSupported(); 5384 5385 final int managedProfileUserId = CALLER_USER_HANDLE; 5386 final int managedProfileAdminUid = 5387 UserHandle.getUid(managedProfileUserId, DpmMockContext.SYSTEM_UID); 5388 mContext.binder.callingUid = managedProfileAdminUid; 5389 addManagedProfile(admin1, managedProfileAdminUid, admin1, VERSION_CODES.R); 5390 5391 dpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_COMPLEX); 5392 dpm.setPasswordMinimumLength(admin1, 8); 5393 dpm.setPasswordMinimumLetters(admin1, 1); 5394 dpm.setPasswordMinimumNumeric(admin1, 2); 5395 dpm.setPasswordMinimumSymbols(admin1, 3); 5396 5397 parentDpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_SOMETHING); 5398 5399 PasswordMetrics deviceMetrics = 5400 dpms.getPasswordMinimumMetrics(UserHandle.USER_SYSTEM, true); 5401 assertThat(deviceMetrics.credType).isEqualTo(LockPatternUtils.CREDENTIAL_TYPE_PATTERN); 5402 5403 PasswordMetrics allMetrics = 5404 dpms.getPasswordMinimumMetrics(UserHandle.USER_SYSTEM, false); 5405 assertThat(allMetrics.credType).isEqualTo(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD); 5406 assertThat(allMetrics.length).isEqualTo(8); 5407 assertThat(allMetrics.letters).isEqualTo(1); 5408 assertThat(allMetrics.numeric).isEqualTo(2); 5409 assertThat(allMetrics.symbols).isEqualTo(3); 5410 } 5411 5412 @Test testCanSetPasswordRequirementOnParentPreS()5413 public void testCanSetPasswordRequirementOnParentPreS() throws Exception { 5414 assumeDeprecatedPasswordApisSupported(); 5415 5416 final int managedProfileUserId = CALLER_USER_HANDLE; 5417 final int managedProfileAdminUid = 5418 UserHandle.getUid(managedProfileUserId, DpmMockContext.SYSTEM_UID); 5419 mContext.binder.callingUid = managedProfileAdminUid; 5420 addManagedProfile(admin1, managedProfileAdminUid, admin1, VERSION_CODES.R); 5421 dpms.mMockInjector.setChangeEnabledForPackage(165573442L, false, 5422 admin1.getPackageName(), managedProfileUserId); 5423 5424 parentDpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_COMPLEX); 5425 assertThat(parentDpm.getPasswordQuality(admin1)) 5426 .isEqualTo(DevicePolicyManager.PASSWORD_QUALITY_COMPLEX); 5427 } 5428 5429 @Test testCannotSetPasswordRequirementOnParent()5430 public void testCannotSetPasswordRequirementOnParent() throws Exception { 5431 assumeDeprecatedPasswordApisSupported(); 5432 5433 final int managedProfileUserId = CALLER_USER_HANDLE; 5434 final int managedProfileAdminUid = 5435 UserHandle.getUid(managedProfileUserId, DpmMockContext.SYSTEM_UID); 5436 mContext.binder.callingUid = managedProfileAdminUid; 5437 addManagedProfile(admin1, managedProfileAdminUid, admin1); 5438 dpms.mMockInjector.setChangeEnabledForPackage(165573442L, true, 5439 admin1.getPackageName(), managedProfileUserId); 5440 5441 try { 5442 assertExpectException(SecurityException.class, null, () -> 5443 parentDpm.setPasswordQuality( 5444 admin1, DevicePolicyManager.PASSWORD_QUALITY_COMPLEX)); 5445 } finally { 5446 dpms.mMockInjector.clearEnabledChanges(); 5447 } 5448 } 5449 5450 @Test isActivePasswordSufficient_SeparateWorkChallenge_ProfileQualityRequirementMet()5451 public void isActivePasswordSufficient_SeparateWorkChallenge_ProfileQualityRequirementMet() 5452 throws Exception { 5453 assumeDeprecatedPasswordApisSupported(); 5454 5455 // Create work profile with empty separate challenge 5456 final int managedProfileUserId = 15; 5457 final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); 5458 addManagedProfileForPasswordTests(managedProfileUserId, managedProfileAdminUid, 5459 /* separateChallenge */ true); 5460 5461 // Set profile password quality requirement. No password added yet so 5462 // profile.isActivePasswordSufficient should return false 5463 mContext.binder.callingUid = managedProfileAdminUid; 5464 dpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC); 5465 assertThat(dpm.isActivePasswordSufficient()).isFalse(); 5466 assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); 5467 5468 // Set a work challenge and verify profile.isActivePasswordSufficient is now true 5469 when(getServices().lockSettingsInternal.getUserPasswordMetrics(managedProfileUserId)) 5470 .thenReturn(computeForPasswordOrPin("abcdXYZ5".getBytes(), /* isPin */ false)); 5471 assertThat(dpm.isActivePasswordSufficient()).isTrue(); 5472 assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); 5473 } 5474 5475 @Test isActivePasswordSufficient_SeparateWorkChallenge_ProfileComplexityRequirementMet()5476 public void isActivePasswordSufficient_SeparateWorkChallenge_ProfileComplexityRequirementMet() 5477 throws Exception { 5478 assumeDeprecatedPasswordApisSupported(); 5479 5480 // Create work profile with empty separate challenge 5481 final int managedProfileUserId = 15; 5482 final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); 5483 addManagedProfileForPasswordTests(managedProfileUserId, managedProfileAdminUid, 5484 /* separateChallenge */ true); 5485 5486 // Set profile password complexity requirement. No password added yet so 5487 // profile.isActivePasswordSufficient should return false 5488 mContext.binder.callingUid = managedProfileAdminUid; 5489 dpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_MEDIUM); 5490 assertThat(dpm.isActivePasswordSufficient()).isFalse(); 5491 assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); 5492 5493 // Set a work challenge and verify profile.isActivePasswordSufficient is now true 5494 when(getServices().lockSettingsInternal.getUserPasswordMetrics(managedProfileUserId)) 5495 .thenReturn(computeForPasswordOrPin("5156".getBytes(), /* isPin */ true)); 5496 assertThat(dpm.isActivePasswordSufficient()).isTrue(); 5497 assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); 5498 } 5499 5500 @Test isActivePasswordSufficient_SeparateWorkChallenge_ParentQualityRequirementMet()5501 public void isActivePasswordSufficient_SeparateWorkChallenge_ParentQualityRequirementMet() 5502 throws Exception { 5503 assumeDeprecatedPasswordApisSupported(); 5504 5505 // Create work profile with empty separate challenge 5506 final int managedProfileUserId = 15; 5507 final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); 5508 addManagedProfileForPasswordTests(managedProfileUserId, managedProfileAdminUid, 5509 /* separateChallenge */ true); 5510 5511 // Set parent password quality requirement. No password added yet so 5512 // parent.isActivePasswordSufficient should return false 5513 mContext.binder.callingUid = managedProfileAdminUid; 5514 parentDpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX); 5515 assertThat(dpm.isActivePasswordSufficient()).isTrue(); 5516 assertThat(parentDpm.isActivePasswordSufficient()).isFalse(); 5517 5518 // Set a device lockscreen and verify parent.isActivePasswordSufficient is now true 5519 when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM)) 5520 .thenReturn(computeForPasswordOrPin("acbdXYZ5".getBytes(), /* isPin */ false)); 5521 assertThat(dpm.isActivePasswordSufficient()).isTrue(); 5522 assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); 5523 } 5524 5525 @Test isActivePasswordSufficient_SeparateWorkChallenge_ParentComplexityRequirementMet()5526 public void isActivePasswordSufficient_SeparateWorkChallenge_ParentComplexityRequirementMet() 5527 throws Exception { 5528 // Create work profile with empty separate challenge 5529 final int managedProfileUserId = 15; 5530 final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); 5531 addManagedProfileForPasswordTests(managedProfileUserId, managedProfileAdminUid, 5532 /* separateChallenge */ true); 5533 5534 // Set parent password complexity requirement. No password added yet so 5535 // parent.isActivePasswordSufficient should return false 5536 mContext.binder.callingUid = managedProfileAdminUid; 5537 parentDpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_LOW); 5538 assertThat(dpm.isActivePasswordSufficient()).isTrue(); 5539 assertThat(parentDpm.isActivePasswordSufficient()).isFalse(); 5540 5541 // Set a device lockscreen and verify parent.isActivePasswordSufficient is now true 5542 when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM)) 5543 .thenReturn(computeForPasswordOrPin("1234".getBytes(), /* isPin */ true)); 5544 assertThat(dpm.isActivePasswordSufficient()).isTrue(); 5545 assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); 5546 } 5547 5548 @Test isActivePasswordSufficient_UnifiedWorkChallenge_ProfileQualityRequirementMet()5549 public void isActivePasswordSufficient_UnifiedWorkChallenge_ProfileQualityRequirementMet() 5550 throws Exception { 5551 assumeDeprecatedPasswordApisSupported(); 5552 5553 // Create work profile with unified challenge 5554 final int managedProfileUserId = 15; 5555 final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); 5556 addManagedProfileForPasswordTests(managedProfileUserId, managedProfileAdminUid, 5557 /* separateChallenge */ false); 5558 5559 // Set profile password quality requirement. No password added yet so 5560 // {profile, parent}.isActivePasswordSufficient should return false 5561 mContext.binder.callingUid = managedProfileAdminUid; 5562 dpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC); 5563 assertThat(dpm.isActivePasswordSufficient()).isFalse(); 5564 assertThat(parentDpm.isActivePasswordSufficient()).isFalse(); 5565 5566 // Set a device lockscreen and verify {profile, parent}.isActivePasswordSufficient is true 5567 when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM)) 5568 .thenReturn(computeForPasswordOrPin("abcdXYZ5".getBytes(), /* isPin */ false)); 5569 assertThat(dpm.isActivePasswordSufficient()).isTrue(); 5570 assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); 5571 } 5572 5573 @Test isActivePasswordSufficient_UnifiedWorkChallenge_ProfileComplexityRequirementMet()5574 public void isActivePasswordSufficient_UnifiedWorkChallenge_ProfileComplexityRequirementMet() 5575 throws Exception { 5576 // Create work profile with unified challenge 5577 final int managedProfileUserId = 15; 5578 final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); 5579 addManagedProfileForPasswordTests(managedProfileUserId, managedProfileAdminUid, 5580 /* separateChallenge */ false); 5581 5582 // Set profile password complexity requirement. No password added yet so 5583 // {profile, parent}.isActivePasswordSufficient should return false 5584 mContext.binder.callingUid = managedProfileAdminUid; 5585 dpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_HIGH); 5586 assertThat(dpm.isActivePasswordSufficient()).isFalse(); 5587 assertThat(parentDpm.isActivePasswordSufficient()).isFalse(); 5588 5589 // Set a device lockscreen and verify {profile, parent}.isActivePasswordSufficient is true 5590 when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM)) 5591 .thenReturn(computeForPasswordOrPin("51567548".getBytes(), /* isPin */ true)); 5592 assertThat(dpm.isActivePasswordSufficient()).isTrue(); 5593 assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); 5594 } 5595 5596 @Test isActivePasswordSufficient_UnifiedWorkChallenge_ParentQualityRequirementMet()5597 public void isActivePasswordSufficient_UnifiedWorkChallenge_ParentQualityRequirementMet() 5598 throws Exception { 5599 assumeDeprecatedPasswordApisSupported(); 5600 5601 // Create work profile with unified challenge 5602 final int managedProfileUserId = 15; 5603 final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); 5604 addManagedProfileForPasswordTests(managedProfileUserId, managedProfileAdminUid, 5605 /* separateChallenge */ false); 5606 5607 // Set parent password quality requirement. No password added yet so 5608 // {profile, parent}.isActivePasswordSufficient should return false 5609 mContext.binder.callingUid = managedProfileAdminUid; 5610 parentDpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC); 5611 assertThat(dpm.isActivePasswordSufficient()).isFalse(); 5612 assertThat(parentDpm.isActivePasswordSufficient()).isFalse(); 5613 5614 // Set a device lockscreen and verify {profile, parent}.isActivePasswordSufficient is true 5615 when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM)) 5616 .thenReturn(computeForPasswordOrPin("abcdXYZ5".getBytes(), /* isPin */ false)); 5617 assertThat(dpm.isActivePasswordSufficient()).isTrue(); 5618 assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); 5619 } 5620 5621 @Test isActivePasswordSufficient_UnifiedWorkChallenge_ParentComplexityRequirementMet()5622 public void isActivePasswordSufficient_UnifiedWorkChallenge_ParentComplexityRequirementMet() 5623 throws Exception { 5624 // Create work profile with unified challenge 5625 final int managedProfileUserId = 15; 5626 final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); 5627 addManagedProfileForPasswordTests(managedProfileUserId, managedProfileAdminUid, 5628 /* separateChallenge */ false); 5629 5630 // Set parent password complexity requirement. No password added yet so 5631 // {profile, parent}.isActivePasswordSufficient should return false 5632 mContext.binder.callingUid = managedProfileAdminUid; 5633 parentDpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_MEDIUM); 5634 assertThat(dpm.isActivePasswordSufficient()).isFalse(); 5635 assertThat(parentDpm.isActivePasswordSufficient()).isFalse(); 5636 5637 // Set a device lockscreen and verify {profile, parent}.isActivePasswordSufficient is true 5638 when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM)) 5639 .thenReturn(computeForPasswordOrPin("5156".getBytes(), /* isPin */ true)); 5640 assertThat(dpm.isActivePasswordSufficient()).isTrue(); 5641 assertThat(parentDpm.isActivePasswordSufficient()).isTrue(); 5642 } 5643 addManagedProfileForPasswordTests(int userId, int adminUid, boolean separateChallenge)5644 private void addManagedProfileForPasswordTests(int userId, int adminUid, 5645 boolean separateChallenge) throws Exception { 5646 addManagedProfile(admin1, adminUid, admin1); 5647 when(getServices().userManager.getProfileParent(userId)) 5648 .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0)); 5649 doReturn(separateChallenge).when(getServices().lockPatternUtils) 5650 .isSeparateProfileChallengeEnabled(userId); 5651 when(getServices().userManager.getCredentialOwnerProfile(userId)) 5652 .thenReturn(separateChallenge ? userId : UserHandle.USER_SYSTEM); 5653 when(getServices().lockSettingsInternal.getUserPasswordMetrics(userId)) 5654 .thenReturn(new PasswordMetrics(CREDENTIAL_TYPE_NONE)); 5655 when(getServices().lockSettingsInternal.getUserPasswordMetrics(UserHandle.USER_SYSTEM)) 5656 .thenReturn(new PasswordMetrics(CREDENTIAL_TYPE_NONE)); 5657 } 5658 5659 @Test testPasswordQualityAppliesToParentPreS()5660 public void testPasswordQualityAppliesToParentPreS() throws Exception { 5661 assumeDeprecatedPasswordApisSupported(); 5662 5663 final int managedProfileUserId = CALLER_USER_HANDLE; 5664 final int managedProfileAdminUid = 5665 UserHandle.getUid(managedProfileUserId, DpmMockContext.SYSTEM_UID); 5666 mContext.binder.callingUid = managedProfileAdminUid; 5667 addManagedProfile(admin1, managedProfileAdminUid, admin1, VERSION_CODES.R); 5668 when(getServices().userManager.getProfileParent(CALLER_USER_HANDLE)) 5669 .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0)); 5670 5671 dpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_COMPLEX); 5672 assertThat(parentDpm.getPasswordQuality(null)) 5673 .isEqualTo(DevicePolicyManager.PASSWORD_QUALITY_COMPLEX); 5674 } 5675 5676 @Test testPasswordQualityDoesNotApplyToParentPostS()5677 public void testPasswordQualityDoesNotApplyToParentPostS() throws Exception { 5678 final int managedProfileUserId = CALLER_USER_HANDLE; 5679 final int managedProfileAdminUid = 5680 UserHandle.getUid(managedProfileUserId, DpmMockContext.SYSTEM_UID); 5681 mContext.binder.callingUid = managedProfileAdminUid; 5682 addManagedProfile(admin1, managedProfileAdminUid, admin1, VERSION_CODES.R); 5683 5684 dpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_COMPLEX); 5685 assertThat(parentDpm.getPasswordQuality(admin1)) 5686 .isEqualTo(DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED); 5687 } 5688 setActivePasswordState(PasswordMetrics passwordMetrics)5689 private void setActivePasswordState(PasswordMetrics passwordMetrics) 5690 throws Exception { 5691 final int userHandle = UserHandle.getUserId(mContext.binder.callingUid); 5692 final long ident = mContext.binder.clearCallingIdentity(); 5693 5694 when(getServices().lockSettingsInternal.getUserPasswordMetrics(userHandle)) 5695 .thenReturn(passwordMetrics); 5696 dpm.reportPasswordChanged(userHandle); 5697 5698 verify(mContext.spiedContext, times(1)).sendBroadcastAsUser( 5699 MockUtils.checkIntentAction( 5700 DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED), 5701 MockUtils.checkUserHandle(userHandle)); 5702 5703 final Intent intent = new Intent(DeviceAdminReceiver.ACTION_PASSWORD_CHANGED); 5704 intent.setComponent(admin1); 5705 intent.putExtra(Intent.EXTRA_USER, UserHandle.of(userHandle)); 5706 5707 verify(mContext.spiedContext, times(1)).sendBroadcastAsUser( 5708 MockUtils.checkIntent(intent), 5709 MockUtils.checkUserHandle(userHandle), 5710 eq(null), 5711 any()); 5712 5713 // CertificateMonitor.updateInstalledCertificates is called on the background thread, 5714 // let it finish with system uid, otherwise it will throw and crash. 5715 flushTasks(dpms); 5716 5717 mContext.binder.restoreCallingIdentity(ident); 5718 } 5719 5720 @Test testIsCurrentInputMethodSetByOwnerForDeviceOwner()5721 public void testIsCurrentInputMethodSetByOwnerForDeviceOwner() throws Exception { 5722 final String currentIme = Settings.Secure.DEFAULT_INPUT_METHOD; 5723 final Uri currentImeUri = Settings.Secure.getUriFor(currentIme); 5724 final int deviceOwnerUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 5725 final int firstUserSystemUid = UserHandle.getUid(UserHandle.USER_SYSTEM, 5726 DpmMockContext.SYSTEM_UID); 5727 final int secondUserSystemUid = UserHandle.getUid(CALLER_USER_HANDLE, 5728 DpmMockContext.SYSTEM_UID); 5729 5730 // Set up a device owner. 5731 mContext.binder.callingUid = deviceOwnerUid; 5732 setupDeviceOwner(); 5733 5734 // First and second user set IMEs manually. 5735 mContext.binder.callingUid = firstUserSystemUid; 5736 assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse(); 5737 mContext.binder.callingUid = secondUserSystemUid; 5738 assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse(); 5739 5740 // Device owner changes IME for first user. 5741 mContext.binder.callingUid = deviceOwnerUid; 5742 when(getServices().settings.settingsSecureGetStringForUser(currentIme, 5743 UserHandle.USER_SYSTEM)).thenReturn("ime1"); 5744 dpm.setSecureSetting(admin1, currentIme, "ime2"); 5745 verify(getServices().settings).settingsSecurePutStringForUser(currentIme, "ime2", 5746 UserHandle.USER_SYSTEM); 5747 reset(getServices().settings); 5748 dpms.notifyChangeToContentObserver(currentImeUri, UserHandle.USER_SYSTEM); 5749 mContext.binder.callingUid = firstUserSystemUid; 5750 assertThat(dpm.isCurrentInputMethodSetByOwner()).isTrue(); 5751 mContext.binder.callingUid = secondUserSystemUid; 5752 assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse(); 5753 5754 // Second user changes IME manually. 5755 dpms.notifyChangeToContentObserver(currentImeUri, CALLER_USER_HANDLE); 5756 mContext.binder.callingUid = firstUserSystemUid; 5757 assertThat(dpm.isCurrentInputMethodSetByOwner()).isTrue(); 5758 mContext.binder.callingUid = secondUserSystemUid; 5759 assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse(); 5760 5761 // First user changes IME manually. 5762 dpms.notifyChangeToContentObserver(currentImeUri, UserHandle.USER_SYSTEM); 5763 mContext.binder.callingUid = firstUserSystemUid; 5764 assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse(); 5765 mContext.binder.callingUid = secondUserSystemUid; 5766 assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse(); 5767 5768 // Device owner changes IME for first user again. 5769 mContext.binder.callingUid = deviceOwnerUid; 5770 when(getServices().settings.settingsSecureGetStringForUser(currentIme, 5771 UserHandle.USER_SYSTEM)).thenReturn("ime2"); 5772 dpm.setSecureSetting(admin1, currentIme, "ime3"); 5773 verify(getServices().settings).settingsSecurePutStringForUser(currentIme, "ime3", 5774 UserHandle.USER_SYSTEM); 5775 dpms.notifyChangeToContentObserver(currentImeUri, UserHandle.USER_SYSTEM); 5776 mContext.binder.callingUid = firstUserSystemUid; 5777 assertThat(dpm.isCurrentInputMethodSetByOwner()).isTrue(); 5778 mContext.binder.callingUid = secondUserSystemUid; 5779 assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse(); 5780 5781 // Restarting the DPMS should not lose information. 5782 initializeDpms(); 5783 mContext.binder.callingUid = firstUserSystemUid; 5784 assertThat(dpm.isCurrentInputMethodSetByOwner()).isTrue(); 5785 mContext.binder.callingUid = secondUserSystemUid; 5786 assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse(); 5787 5788 // Device owner can find out whether it set the current IME itself. 5789 mContext.binder.callingUid = deviceOwnerUid; 5790 assertThat(dpm.isCurrentInputMethodSetByOwner()).isTrue(); 5791 5792 // Removing the device owner should clear the information that it set the current IME. 5793 clearDeviceOwner(); 5794 mContext.binder.callingUid = firstUserSystemUid; 5795 assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse(); 5796 mContext.binder.callingUid = secondUserSystemUid; 5797 assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse(); 5798 } 5799 5800 @Test testIsCurrentInputMethodSetByOwnerForProfileOwner()5801 public void testIsCurrentInputMethodSetByOwnerForProfileOwner() throws Exception { 5802 final String currentIme = Settings.Secure.DEFAULT_INPUT_METHOD; 5803 final Uri currentImeUri = Settings.Secure.getUriFor(currentIme); 5804 final int profileOwnerUid = DpmMockContext.CALLER_UID; 5805 final int firstUserSystemUid = UserHandle.getUid(UserHandle.USER_SYSTEM, 5806 DpmMockContext.SYSTEM_UID); 5807 final int secondUserSystemUid = UserHandle.getUid(CALLER_USER_HANDLE, 5808 DpmMockContext.SYSTEM_UID); 5809 5810 // Set up a profile owner. 5811 mContext.binder.callingUid = profileOwnerUid; 5812 setupProfileOwner(); 5813 5814 // First and second user set IMEs manually. 5815 mContext.binder.callingUid = firstUserSystemUid; 5816 assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse(); 5817 mContext.binder.callingUid = secondUserSystemUid; 5818 assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse(); 5819 5820 // Profile owner changes IME for second user. 5821 mContext.binder.callingUid = profileOwnerUid; 5822 when(getServices().settings.settingsSecureGetStringForUser(currentIme, 5823 CALLER_USER_HANDLE)).thenReturn("ime1"); 5824 dpm.setSecureSetting(admin1, currentIme, "ime2"); 5825 verify(getServices().settings).settingsSecurePutStringForUser(currentIme, "ime2", 5826 CALLER_USER_HANDLE); 5827 reset(getServices().settings); 5828 dpms.notifyChangeToContentObserver(currentImeUri, CALLER_USER_HANDLE); 5829 mContext.binder.callingUid = firstUserSystemUid; 5830 assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse(); 5831 mContext.binder.callingUid = secondUserSystemUid; 5832 assertThat(dpm.isCurrentInputMethodSetByOwner()).isTrue(); 5833 5834 // First user changes IME manually. 5835 dpms.notifyChangeToContentObserver(currentImeUri, UserHandle.USER_SYSTEM); 5836 mContext.binder.callingUid = firstUserSystemUid; 5837 assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse(); 5838 mContext.binder.callingUid = secondUserSystemUid; 5839 assertThat(dpm.isCurrentInputMethodSetByOwner()).isTrue(); 5840 5841 // Second user changes IME manually. 5842 dpms.notifyChangeToContentObserver(currentImeUri, CALLER_USER_HANDLE); 5843 mContext.binder.callingUid = firstUserSystemUid; 5844 assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse(); 5845 mContext.binder.callingUid = secondUserSystemUid; 5846 assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse(); 5847 5848 // Profile owner changes IME for second user again. 5849 mContext.binder.callingUid = profileOwnerUid; 5850 when(getServices().settings.settingsSecureGetStringForUser(currentIme, 5851 CALLER_USER_HANDLE)).thenReturn("ime2"); 5852 dpm.setSecureSetting(admin1, currentIme, "ime3"); 5853 verify(getServices().settings).settingsSecurePutStringForUser(currentIme, "ime3", 5854 CALLER_USER_HANDLE); 5855 dpms.notifyChangeToContentObserver(currentImeUri, CALLER_USER_HANDLE); 5856 mContext.binder.callingUid = firstUserSystemUid; 5857 assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse(); 5858 mContext.binder.callingUid = secondUserSystemUid; 5859 assertThat(dpm.isCurrentInputMethodSetByOwner()).isTrue(); 5860 5861 // Restarting the DPMS should not lose information. 5862 initializeDpms(); 5863 mContext.binder.callingUid = firstUserSystemUid; 5864 assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse(); 5865 mContext.binder.callingUid = secondUserSystemUid; 5866 assertThat(dpm.isCurrentInputMethodSetByOwner()).isTrue(); 5867 5868 // Profile owner can find out whether it set the current IME itself. 5869 mContext.binder.callingUid = profileOwnerUid; 5870 assertThat(dpm.isCurrentInputMethodSetByOwner()).isTrue(); 5871 5872 // Removing the profile owner should clear the information that it set the current IME. 5873 dpm.clearProfileOwner(admin1); 5874 mContext.binder.callingUid = firstUserSystemUid; 5875 assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse(); 5876 mContext.binder.callingUid = secondUserSystemUid; 5877 assertThat(dpm.isCurrentInputMethodSetByOwner()).isFalse(); 5878 } 5879 5880 @Test testSetPermittedCrossProfileNotificationListeners_unavailableForDo()5881 public void testSetPermittedCrossProfileNotificationListeners_unavailableForDo() 5882 throws Exception { 5883 // Set up a device owner. 5884 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 5885 setupDeviceOwner(); 5886 assertSetPermittedCrossProfileNotificationListenersUnavailable(mContext.binder.callingUid); 5887 } 5888 5889 @Test testSetPermittedCrossProfileNotificationListeners_unavailableForPoOnUser()5890 public void testSetPermittedCrossProfileNotificationListeners_unavailableForPoOnUser() 5891 throws Exception { 5892 // Set up a profile owner. 5893 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 5894 setupProfileOwner(); 5895 assertSetPermittedCrossProfileNotificationListenersUnavailable(mContext.binder.callingUid); 5896 } 5897 assertSetPermittedCrossProfileNotificationListenersUnavailable( int adminUid)5898 private void assertSetPermittedCrossProfileNotificationListenersUnavailable( 5899 int adminUid) throws Exception { 5900 mContext.binder.callingUid = adminUid; 5901 final int userId = UserHandle.getUserId(adminUid); 5902 5903 final String packageName = "some.package"; 5904 assertThat(dpms.setPermittedCrossProfileNotificationListeners( 5905 admin1, Collections.singletonList(packageName))).isFalse(); 5906 assertThat(dpms.getPermittedCrossProfileNotificationListeners(admin1)).isNull(); 5907 5908 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 5909 assertThat(dpms.isNotificationListenerServicePermitted(packageName, userId)).isTrue(); 5910 5911 // Attempt to set to empty list (which means no listener is allowlisted) 5912 mContext.binder.callingUid = adminUid; 5913 assertThat(dpms.setPermittedCrossProfileNotificationListeners( 5914 admin1, emptyList())).isFalse(); 5915 assertThat(dpms.getPermittedCrossProfileNotificationListeners(admin1)).isNull(); 5916 5917 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 5918 assertThat(dpms.isNotificationListenerServicePermitted(packageName, userId)).isTrue(); 5919 } 5920 5921 @Test testIsNotificationListenerServicePermitted_onlySystemCanCall()5922 public void testIsNotificationListenerServicePermitted_onlySystemCanCall() throws Exception { 5923 // Set up a managed profile 5924 final int MANAGED_PROFILE_USER_ID = 15; 5925 final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 19436); 5926 addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1); 5927 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 5928 5929 final String permittedListener = "some.package"; 5930 setupPackageInPackageManager( 5931 permittedListener, 5932 UserHandle.USER_SYSTEM, // We check the packageInfo from the primary user. 5933 /*appId=*/ 12345, /*flags=*/ 0); 5934 5935 assertThat(dpms.setPermittedCrossProfileNotificationListeners( 5936 admin1, Collections.singletonList(permittedListener))).isTrue(); 5937 5938 // isNotificationListenerServicePermitted should throw if not called from System. 5939 assertExpectException(SecurityException.class, /* messageRegex= */ null, 5940 () -> dpms.isNotificationListenerServicePermitted( 5941 permittedListener, MANAGED_PROFILE_USER_ID)); 5942 5943 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 5944 assertThat(dpms.isNotificationListenerServicePermitted( 5945 permittedListener, MANAGED_PROFILE_USER_ID)).isTrue(); 5946 } 5947 5948 @Test testSetPermittedCrossProfileNotificationListeners_managedProfile()5949 public void testSetPermittedCrossProfileNotificationListeners_managedProfile() 5950 throws Exception { 5951 // Set up a managed profile 5952 final int MANAGED_PROFILE_USER_ID = 15; 5953 final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 19436); 5954 addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1); 5955 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 5956 5957 final String permittedListener = "permitted.package"; 5958 int appId = 12345; 5959 setupPackageInPackageManager( 5960 permittedListener, 5961 UserHandle.USER_SYSTEM, // We check the packageInfo from the primary user. 5962 appId, /*flags=*/ 0); 5963 5964 final String notPermittedListener = "not.permitted.package"; 5965 setupPackageInPackageManager( 5966 notPermittedListener, 5967 UserHandle.USER_SYSTEM, // We check the packageInfo from the primary user. 5968 ++appId, /*flags=*/ 0); 5969 5970 final String systemListener = "system.package"; 5971 setupPackageInPackageManager( 5972 systemListener, 5973 UserHandle.USER_SYSTEM, // We check the packageInfo from the primary user. 5974 ++appId, ApplicationInfo.FLAG_SYSTEM); 5975 5976 // By default all packages are allowed 5977 assertThat(dpms.getPermittedCrossProfileNotificationListeners(admin1)).isNull(); 5978 5979 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 5980 assertThat(dpms.isNotificationListenerServicePermitted( 5981 permittedListener, MANAGED_PROFILE_USER_ID)).isTrue(); 5982 assertThat(dpms.isNotificationListenerServicePermitted( 5983 notPermittedListener, MANAGED_PROFILE_USER_ID)).isTrue(); 5984 assertThat(dpms.isNotificationListenerServicePermitted( 5985 systemListener, MANAGED_PROFILE_USER_ID)).isTrue(); 5986 5987 // Setting only one package in the allowlist 5988 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 5989 assertThat(dpms.setPermittedCrossProfileNotificationListeners( 5990 admin1, Collections.singletonList(permittedListener))).isTrue(); 5991 final List<String> permittedListeners = 5992 dpms.getPermittedCrossProfileNotificationListeners(admin1); 5993 assertThat(permittedListeners.size()).isEqualTo(1); 5994 assertThat(permittedListeners.get(0)).isEqualTo(permittedListener); 5995 5996 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 5997 assertThat(dpms.isNotificationListenerServicePermitted( 5998 permittedListener, MANAGED_PROFILE_USER_ID)).isTrue(); 5999 assertThat(dpms.isNotificationListenerServicePermitted( 6000 notPermittedListener, MANAGED_PROFILE_USER_ID)).isFalse(); 6001 // System packages are always allowed (even if not in the allowlist) 6002 assertThat(dpms.isNotificationListenerServicePermitted( 6003 systemListener, MANAGED_PROFILE_USER_ID)).isTrue(); 6004 6005 // Setting an empty allowlist - only system listeners allowed 6006 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 6007 assertThat(dpms.setPermittedCrossProfileNotificationListeners( 6008 admin1, emptyList())).isTrue(); 6009 assertThat(dpms.getPermittedCrossProfileNotificationListeners(admin1).size()).isEqualTo(0); 6010 6011 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 6012 assertThat(dpms.isNotificationListenerServicePermitted( 6013 permittedListener, MANAGED_PROFILE_USER_ID)).isFalse(); 6014 assertThat(dpms.isNotificationListenerServicePermitted( 6015 notPermittedListener, MANAGED_PROFILE_USER_ID)).isFalse(); 6016 // System packages are always allowed (even if not in the allowlist) 6017 assertThat(dpms.isNotificationListenerServicePermitted( 6018 systemListener, MANAGED_PROFILE_USER_ID)).isTrue(); 6019 6020 // Setting a null allowlist - all listeners allowed 6021 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 6022 assertThat(dpms.setPermittedCrossProfileNotificationListeners(admin1, null)).isTrue(); 6023 assertThat(dpms.getPermittedCrossProfileNotificationListeners(admin1)).isNull(); 6024 6025 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 6026 assertThat(dpms.isNotificationListenerServicePermitted( 6027 permittedListener, MANAGED_PROFILE_USER_ID)).isTrue(); 6028 assertThat(dpms.isNotificationListenerServicePermitted( 6029 notPermittedListener, MANAGED_PROFILE_USER_ID)).isTrue(); 6030 assertThat(dpms.isNotificationListenerServicePermitted( 6031 systemListener, MANAGED_PROFILE_USER_ID)).isTrue(); 6032 } 6033 6034 @Test testSetPermittedCrossProfileNotificationListeners_doesNotAffectPrimaryProfile()6035 public void testSetPermittedCrossProfileNotificationListeners_doesNotAffectPrimaryProfile() 6036 throws Exception { 6037 // Set up a managed profile 6038 final int MANAGED_PROFILE_USER_ID = 15; 6039 final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 19436); 6040 addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1); 6041 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 6042 6043 final String nonSystemPackage = "non.system.package"; 6044 int appId = 12345; 6045 setupPackageInPackageManager( 6046 nonSystemPackage, 6047 UserHandle.USER_SYSTEM, // We check the packageInfo from the primary user. 6048 appId, /*flags=*/ 0); 6049 6050 final String systemListener = "system.package"; 6051 setupPackageInPackageManager( 6052 systemListener, 6053 UserHandle.USER_SYSTEM, // We check the packageInfo from the primary user. 6054 ++appId, ApplicationInfo.FLAG_SYSTEM); 6055 6056 // By default all packages are allowed (for all profiles) 6057 assertThat(dpms.getPermittedCrossProfileNotificationListeners(admin1)).isNull(); 6058 6059 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 6060 assertThat(dpms.isNotificationListenerServicePermitted( 6061 nonSystemPackage, MANAGED_PROFILE_USER_ID)).isTrue(); 6062 assertThat(dpms.isNotificationListenerServicePermitted( 6063 systemListener, MANAGED_PROFILE_USER_ID)).isTrue(); 6064 assertThat(dpms.isNotificationListenerServicePermitted( 6065 nonSystemPackage, UserHandle.USER_SYSTEM)).isTrue(); 6066 assertThat(dpms.isNotificationListenerServicePermitted( 6067 systemListener, UserHandle.USER_SYSTEM)).isTrue(); 6068 6069 // Setting an empty allowlist - only system listeners allowed in managed profile, but 6070 // all allowed in primary profile 6071 mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; 6072 assertThat(dpms.setPermittedCrossProfileNotificationListeners( 6073 admin1, emptyList())).isTrue(); 6074 assertThat(dpms.getPermittedCrossProfileNotificationListeners(admin1).size()).isEqualTo(0); 6075 6076 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 6077 assertThat(dpms.isNotificationListenerServicePermitted( 6078 nonSystemPackage, MANAGED_PROFILE_USER_ID)).isFalse(); 6079 assertThat(dpms.isNotificationListenerServicePermitted( 6080 systemListener, MANAGED_PROFILE_USER_ID)).isTrue(); 6081 assertThat(dpms.isNotificationListenerServicePermitted( 6082 nonSystemPackage, UserHandle.USER_SYSTEM)).isTrue(); 6083 assertThat(dpms.isNotificationListenerServicePermitted( 6084 systemListener, UserHandle.USER_SYSTEM)).isTrue(); 6085 } 6086 6087 @Test testGetOwnerInstalledCaCertsForDeviceOwner()6088 public void testGetOwnerInstalledCaCertsForDeviceOwner() throws Exception { 6089 mServiceContext.packageName = mRealTestContext.getPackageName(); 6090 mServiceContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 6091 mAdmin1Context.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 6092 setDeviceOwner(); 6093 6094 verifyCanGetOwnerInstalledCaCerts(admin1, mAdmin1Context); 6095 } 6096 6097 @Test testGetOwnerInstalledCaCertsForProfileOwner()6098 public void testGetOwnerInstalledCaCertsForProfileOwner() throws Exception { 6099 mServiceContext.packageName = mRealTestContext.getPackageName(); 6100 mServiceContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 6101 mAdmin1Context.binder.callingUid = DpmMockContext.CALLER_UID; 6102 setAsProfileOwner(admin1); 6103 6104 verifyCanGetOwnerInstalledCaCerts(admin1, mAdmin1Context); 6105 verifyCantGetOwnerInstalledCaCertsProfileOwnerRemoval(admin1, mAdmin1Context); 6106 } 6107 6108 @Test testGetOwnerInstalledCaCertsForDelegate()6109 public void testGetOwnerInstalledCaCertsForDelegate() throws Exception { 6110 mServiceContext.packageName = mRealTestContext.getPackageName(); 6111 mServiceContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 6112 mAdmin1Context.binder.callingUid = DpmMockContext.CALLER_UID; 6113 setAsProfileOwner(admin1); 6114 6115 final DpmMockContext caller = new DpmMockContext(getServices(), mRealTestContext); 6116 caller.packageName = "com.example.delegate"; 6117 caller.binder.callingUid = setupPackageInPackageManager(caller.packageName, 6118 CALLER_USER_HANDLE, 20988, ApplicationInfo.FLAG_HAS_CODE); 6119 6120 // Make caller a delegated cert installer. 6121 runAsCaller(mAdmin1Context, dpms, 6122 dpm -> dpm.setCertInstallerPackage(admin1, caller.packageName)); 6123 6124 verifyCanGetOwnerInstalledCaCerts(null, caller); 6125 verifyCantGetOwnerInstalledCaCertsProfileOwnerRemoval(null, caller); 6126 } 6127 6128 @Test testDisallowSharingIntoProfileSetRestriction()6129 public void testDisallowSharingIntoProfileSetRestriction() { 6130 when(mServiceContext.resources.getString(R.string.config_managed_provisioning_package)) 6131 .thenReturn("com.android.managedprovisioning"); 6132 when(getServices().userManagerInternal.getProfileParentId(anyInt())) 6133 .thenReturn(UserHandle.USER_SYSTEM); 6134 mServiceContext.binder.callingPid = DpmMockContext.SYSTEM_PID; 6135 mServiceContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 6136 Bundle restriction = new Bundle(); 6137 restriction.putBoolean(UserManager.DISALLOW_SHARE_INTO_MANAGED_PROFILE, true); 6138 6139 RestrictionsListener listener = new RestrictionsListener( 6140 mServiceContext, getServices().userManagerInternal, dpms); 6141 listener.onUserRestrictionsChanged(CALLER_USER_HANDLE, restriction, new Bundle()); 6142 6143 verifyDataSharingAppliedBroadcast(); 6144 } 6145 6146 @Test testDisallowSharingIntoProfileClearRestriction()6147 public void testDisallowSharingIntoProfileClearRestriction() { 6148 when(mServiceContext.resources.getString(R.string.config_managed_provisioning_package)) 6149 .thenReturn("com.android.managedprovisioning"); 6150 when(getServices().userManagerInternal.getProfileParentId(anyInt())) 6151 .thenReturn(UserHandle.USER_SYSTEM); 6152 mServiceContext.binder.callingPid = DpmMockContext.SYSTEM_PID; 6153 mServiceContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 6154 Bundle restriction = new Bundle(); 6155 restriction.putBoolean(UserManager.DISALLOW_SHARE_INTO_MANAGED_PROFILE, true); 6156 6157 RestrictionsListener listener = new RestrictionsListener( 6158 mServiceContext, getServices().userManagerInternal, dpms); 6159 listener.onUserRestrictionsChanged(CALLER_USER_HANDLE, new Bundle(), restriction); 6160 6161 verifyDataSharingAppliedBroadcast(); 6162 } 6163 6164 @Test testDisallowSharingIntoProfileUnchanged()6165 public void testDisallowSharingIntoProfileUnchanged() { 6166 RestrictionsListener listener = new RestrictionsListener( 6167 mContext, getServices().userManagerInternal, dpms); 6168 listener.onUserRestrictionsChanged(CALLER_USER_HANDLE, new Bundle(), new Bundle()); 6169 verify(mContext.spiedContext, never()).sendBroadcastAsUser(any(), any()); 6170 } 6171 verifyDataSharingAppliedBroadcast()6172 private void verifyDataSharingAppliedBroadcast() { 6173 Intent expectedIntent = new Intent( 6174 DevicePolicyManager.ACTION_DATA_SHARING_RESTRICTION_APPLIED); 6175 verify(mContext.spiedContext, times(1)).sendBroadcastAsUser( 6176 MockUtils.checkIntent(expectedIntent), 6177 MockUtils.checkUserHandle(CALLER_USER_HANDLE)); 6178 } 6179 6180 @Test testOverrideApnAPIsFailWithPO()6181 public void testOverrideApnAPIsFailWithPO() throws Exception { 6182 when(getServices().packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) 6183 .thenReturn(true); 6184 // FEATURE_TELEPHONY is set in DPMS's constructor and therefore a new DPMS instance 6185 // is created after turning on the feature. 6186 initializeDpms(); 6187 setupProfileOwner(); 6188 ApnSetting apn = (new ApnSetting.Builder()) 6189 .setApnName("test") 6190 .setEntryName("test") 6191 .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT) 6192 .build(); 6193 assertExpectException(SecurityException.class, null, () -> 6194 dpm.addOverrideApn(admin1, apn)); 6195 assertExpectException(SecurityException.class, null, () -> 6196 dpm.updateOverrideApn(admin1, 0, apn)); 6197 assertExpectException(SecurityException.class, null, () -> 6198 dpm.removeOverrideApn(admin1, 0)); 6199 assertExpectException(SecurityException.class, null, () -> 6200 dpm.getOverrideApns(admin1)); 6201 assertExpectException(SecurityException.class, null, () -> 6202 dpm.setOverrideApnsEnabled(admin1, false)); 6203 assertExpectException(SecurityException.class, null, () -> 6204 dpm.isOverrideApnEnabled(admin1)); 6205 } 6206 verifyCanGetOwnerInstalledCaCerts( final ComponentName caller, final DpmMockContext callerContext)6207 private void verifyCanGetOwnerInstalledCaCerts( 6208 final ComponentName caller, final DpmMockContext callerContext) throws Exception { 6209 final String alias = "cert"; 6210 final byte[] caCert = TEST_CA.getBytes(); 6211 6212 // device admin (used for posting the tls notification) 6213 DpmMockContext admin1Context = mAdmin1Context; 6214 if (admin1.getPackageName().equals(callerContext.getPackageName())) { 6215 admin1Context = callerContext; 6216 } 6217 when(admin1Context.resources.getColor(anyInt(), anyObject())).thenReturn(Color.WHITE); 6218 6219 // caller: device admin or delegated certificate installer 6220 callerContext.applicationInfo = new ApplicationInfo(); 6221 final UserHandle callerUser = callerContext.binder.getCallingUserHandle(); 6222 6223 // system_server 6224 final DpmMockContext serviceContext = mContext; 6225 serviceContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 6226 getServices().addPackageContext(callerUser, admin1Context); 6227 getServices().addPackageContext(callerUser, callerContext); 6228 6229 // Install a CA cert. 6230 runAsCaller(callerContext, dpms, (dpm) -> { 6231 when(getServices().keyChainConnection.getService().installCaCertificate(caCert)) 6232 .thenReturn(alias); 6233 assertThat(dpm.installCaCert(caller, caCert)).isTrue(); 6234 when(getServices().keyChainConnection.getService().getUserCaAliases()) 6235 .thenReturn(asSlice(new String[] {alias})); 6236 }); 6237 6238 getServices().injectBroadcast(mServiceContext, 6239 new Intent(KeyChain.ACTION_TRUST_STORE_CHANGED) 6240 .putExtra(Intent.EXTRA_USER_HANDLE, callerUser.getIdentifier()), 6241 callerUser.getIdentifier()); 6242 flushTasks(dpms); 6243 6244 final List<String> ownerInstalledCaCerts = new ArrayList<>(); 6245 6246 // Device Owner / Profile Owner can find out which CA certs were installed by itself. 6247 runAsCaller(admin1Context, dpms, (dpm) -> { 6248 final List<String> installedCaCerts = dpm.getOwnerInstalledCaCerts(callerUser); 6249 assertThat(installedCaCerts).isEqualTo(Collections.singletonList(alias)); 6250 ownerInstalledCaCerts.addAll(installedCaCerts); 6251 }); 6252 6253 // Restarting the DPMS should not lose information. 6254 initializeDpms(); 6255 runAsCaller(admin1Context, dpms, 6256 (dpm) -> assertThat(dpm.getOwnerInstalledCaCerts(callerUser)) 6257 .isEqualTo(ownerInstalledCaCerts)); 6258 6259 // System can find out which CA certs were installed by the Device Owner / Profile Owner. 6260 runAsCaller(serviceContext, dpms, (dpm) -> { 6261 assertThat(dpm.getOwnerInstalledCaCerts(callerUser)).isEqualTo(ownerInstalledCaCerts); 6262 6263 // Remove the CA cert. 6264 reset(getServices().keyChainConnection.getService()); 6265 }); 6266 6267 getServices().injectBroadcast(mServiceContext, 6268 new Intent(KeyChain.ACTION_TRUST_STORE_CHANGED) 6269 .putExtra(Intent.EXTRA_USER_HANDLE, callerUser.getIdentifier()), 6270 callerUser.getIdentifier()); 6271 flushTasks(dpms); 6272 6273 // Verify that the CA cert is no longer reported as installed by the Device Owner / Profile 6274 // Owner. 6275 runAsCaller(admin1Context, dpms, (dpm) -> { 6276 MoreAsserts.assertEmpty(dpm.getOwnerInstalledCaCerts(callerUser)); 6277 }); 6278 } 6279 verifyCantGetOwnerInstalledCaCertsProfileOwnerRemoval( final ComponentName callerName, final DpmMockContext callerContext)6280 private void verifyCantGetOwnerInstalledCaCertsProfileOwnerRemoval( 6281 final ComponentName callerName, final DpmMockContext callerContext) throws Exception { 6282 final String alias = "cert"; 6283 final byte[] caCert = TEST_CA.getBytes(); 6284 6285 // device admin (used for posting the tls notification) 6286 DpmMockContext admin1Context = mAdmin1Context; 6287 if (admin1.getPackageName().equals(callerContext.getPackageName())) { 6288 admin1Context = callerContext; 6289 } 6290 when(admin1Context.resources.getColor(anyInt(), anyObject())).thenReturn(Color.WHITE); 6291 6292 // caller: device admin or delegated certificate installer 6293 callerContext.applicationInfo = new ApplicationInfo(); 6294 final UserHandle callerUser = callerContext.binder.getCallingUserHandle(); 6295 6296 // system_server 6297 final DpmMockContext serviceContext = mContext; 6298 serviceContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 6299 getServices().addPackageContext(callerUser, admin1Context); 6300 getServices().addPackageContext(callerUser, callerContext); 6301 6302 // Install a CA cert as caller 6303 runAsCaller(callerContext, dpms, (dpm) -> { 6304 when(getServices().keyChainConnection.getService().installCaCertificate(caCert)) 6305 .thenReturn(alias); 6306 assertThat(dpm.installCaCert(callerName, caCert)).isTrue(); 6307 }); 6308 6309 // Fake the CA cert as having been installed 6310 when(getServices().keyChainConnection.getService().getUserCaAliases()) 6311 .thenReturn(asSlice(new String[] {alias})); 6312 getServices().injectBroadcast(mServiceContext, 6313 new Intent(KeyChain.ACTION_TRUST_STORE_CHANGED) 6314 .putExtra(Intent.EXTRA_USER_HANDLE, callerUser.getIdentifier()), 6315 callerUser.getIdentifier()); 6316 flushTasks(dpms); 6317 6318 // Removing the Profile Owner should clear the information on which CA certs were installed 6319 runAsCaller(admin1Context, dpms, dpm -> dpm.clearProfileOwner(admin1)); 6320 6321 runAsCaller(serviceContext, dpms, (dpm) -> { 6322 final List<String> ownerInstalledCaCerts = dpm.getOwnerInstalledCaCerts(callerUser); 6323 assertThat(ownerInstalledCaCerts).isNotNull(); 6324 assertThat(ownerInstalledCaCerts.isEmpty()).isTrue(); 6325 }); 6326 } 6327 verifyRebootWipeUserData(boolean wipeEuicc)6328 private void verifyRebootWipeUserData(boolean wipeEuicc) throws Exception { 6329 verify(getServices().recoverySystem).rebootWipeUserData(/*shutdown=*/ eq(false), 6330 /* reason= */ anyString(), /*force=*/ eq(true), eq(wipeEuicc), 6331 /* wipeAdoptableStorage= */ eq(false), /* wipeFactoryResetProtection= */ eq(false)); 6332 } 6333 assertAttestationFlags(int attestationFlags, int[] expectedFlags)6334 private void assertAttestationFlags(int attestationFlags, int[] expectedFlags) { 6335 int[] gotFlags = DevicePolicyManagerService.translateIdAttestationFlags(attestationFlags); 6336 Arrays.sort(gotFlags); 6337 Arrays.sort(expectedFlags); 6338 assertThat(Arrays.equals(expectedFlags, gotFlags)).isTrue(); 6339 } 6340 6341 @Test testTranslationOfIdAttestationFlag()6342 public void testTranslationOfIdAttestationFlag() { 6343 int[] allIdTypes = new int[]{ID_TYPE_SERIAL, ID_TYPE_IMEI, ID_TYPE_MEID}; 6344 int[] correspondingAttUtilsTypes = new int[]{ 6345 AttestationUtils.ID_TYPE_SERIAL, AttestationUtils.ID_TYPE_IMEI, 6346 AttestationUtils.ID_TYPE_MEID}; 6347 6348 // Test translation of zero flags 6349 assertThat(DevicePolicyManagerService.translateIdAttestationFlags(0)).isNull(); 6350 6351 // Test translation of the ID_TYPE_BASE_INFO flag, which should yield an empty, but 6352 // non-null array 6353 assertAttestationFlags(ID_TYPE_BASE_INFO, new int[] {}); 6354 6355 // Test translation of a single flag 6356 assertAttestationFlags(ID_TYPE_BASE_INFO | ID_TYPE_SERIAL, 6357 new int[] {AttestationUtils.ID_TYPE_SERIAL}); 6358 assertAttestationFlags(ID_TYPE_SERIAL, new int[] {AttestationUtils.ID_TYPE_SERIAL}); 6359 6360 // Test translation of two flags 6361 assertAttestationFlags(ID_TYPE_SERIAL | ID_TYPE_IMEI, 6362 new int[] {AttestationUtils.ID_TYPE_IMEI, AttestationUtils.ID_TYPE_SERIAL}); 6363 assertAttestationFlags(ID_TYPE_BASE_INFO | ID_TYPE_MEID | ID_TYPE_SERIAL, 6364 new int[] {AttestationUtils.ID_TYPE_MEID, AttestationUtils.ID_TYPE_SERIAL}); 6365 6366 // Test translation of all three flags 6367 assertAttestationFlags(ID_TYPE_SERIAL | ID_TYPE_IMEI | ID_TYPE_MEID, 6368 new int[] {AttestationUtils.ID_TYPE_IMEI, AttestationUtils.ID_TYPE_SERIAL, 6369 AttestationUtils.ID_TYPE_MEID}); 6370 // Test translation of all three flags 6371 assertAttestationFlags(ID_TYPE_SERIAL | ID_TYPE_IMEI | ID_TYPE_MEID | ID_TYPE_BASE_INFO, 6372 new int[] {AttestationUtils.ID_TYPE_IMEI, AttestationUtils.ID_TYPE_SERIAL, 6373 AttestationUtils.ID_TYPE_MEID}); 6374 } 6375 6376 @Test testRevertDeviceOwnership_noMetadataFile()6377 public void testRevertDeviceOwnership_noMetadataFile() throws Exception { 6378 setDeviceOwner(); 6379 initializeDpms(); 6380 assertThat(getMockTransferMetadataManager().metadataFileExists()).isFalse(); 6381 assertThat(dpms.isDeviceOwner(admin1, UserHandle.USER_SYSTEM)).isTrue(); 6382 assertThat(dpms.isAdminActive(admin1, UserHandle.USER_SYSTEM)).isTrue(); 6383 } 6384 6385 @FlakyTest(bugId = 148934649) 6386 @Test testRevertDeviceOwnership_adminAndDeviceMigrated()6387 public void testRevertDeviceOwnership_adminAndDeviceMigrated() throws Exception { 6388 DpmTestUtils.writeInputStreamToFile( 6389 getRawStream(com.android.frameworks.servicestests.R.raw.active_admin_migrated), 6390 getDeviceOwnerPoliciesFile()); 6391 DpmTestUtils.writeInputStreamToFile( 6392 getRawStream(com.android.frameworks.servicestests.R.raw.device_owner_migrated), 6393 getDeviceOwnerFile()); 6394 assertDeviceOwnershipRevertedWithFakeTransferMetadata(); 6395 } 6396 6397 @FlakyTest(bugId = 148934649) 6398 @Test testRevertDeviceOwnership_deviceNotMigrated()6399 public void testRevertDeviceOwnership_deviceNotMigrated() throws Exception { 6400 DpmTestUtils.writeInputStreamToFile( 6401 getRawStream(com.android.frameworks.servicestests.R.raw.active_admin_migrated), 6402 getDeviceOwnerPoliciesFile()); 6403 DpmTestUtils.writeInputStreamToFile( 6404 getRawStream(com.android.frameworks.servicestests.R.raw.device_owner_not_migrated), 6405 getDeviceOwnerFile()); 6406 assertDeviceOwnershipRevertedWithFakeTransferMetadata(); 6407 } 6408 6409 @Test testRevertDeviceOwnership_adminAndDeviceNotMigrated()6410 public void testRevertDeviceOwnership_adminAndDeviceNotMigrated() throws Exception { 6411 DpmTestUtils.writeInputStreamToFile( 6412 getRawStream(com.android.frameworks.servicestests.R.raw.active_admin_not_migrated), 6413 getDeviceOwnerPoliciesFile()); 6414 DpmTestUtils.writeInputStreamToFile( 6415 getRawStream(com.android.frameworks.servicestests.R.raw.device_owner_not_migrated), 6416 getDeviceOwnerFile()); 6417 assertDeviceOwnershipRevertedWithFakeTransferMetadata(); 6418 } 6419 6420 @Test testRevertProfileOwnership_noMetadataFile()6421 public void testRevertProfileOwnership_noMetadataFile() throws Exception { 6422 setupProfileOwner(); 6423 initializeDpms(); 6424 assertThat(getMockTransferMetadataManager().metadataFileExists()).isFalse(); 6425 assertThat(dpms.isProfileOwner(admin1, CALLER_USER_HANDLE)).isTrue(); 6426 assertThat(dpms.isAdminActive(admin1, CALLER_USER_HANDLE)).isTrue(); 6427 } 6428 6429 @FlakyTest(bugId = 148934649) 6430 @Test testRevertProfileOwnership_adminAndProfileMigrated()6431 public void testRevertProfileOwnership_adminAndProfileMigrated() throws Exception { 6432 getServices().addUser(DpmMockContext.CALLER_USER_HANDLE, 0, 6433 UserManager.USER_TYPE_PROFILE_MANAGED, UserHandle.USER_SYSTEM); 6434 DpmTestUtils.writeInputStreamToFile( 6435 getRawStream(com.android.frameworks.servicestests.R.raw.active_admin_migrated), 6436 getProfileOwnerPoliciesFile()); 6437 DpmTestUtils.writeInputStreamToFile( 6438 getRawStream(com.android.frameworks.servicestests.R.raw.profile_owner_migrated), 6439 getProfileOwnerFile()); 6440 assertProfileOwnershipRevertedWithFakeTransferMetadata(); 6441 } 6442 6443 @FlakyTest(bugId = 148934649) 6444 @Test testRevertProfileOwnership_profileNotMigrated()6445 public void testRevertProfileOwnership_profileNotMigrated() throws Exception { 6446 getServices().addUser(DpmMockContext.CALLER_USER_HANDLE, 0, 6447 UserManager.USER_TYPE_PROFILE_MANAGED, UserHandle.USER_SYSTEM); 6448 DpmTestUtils.writeInputStreamToFile( 6449 getRawStream(com.android.frameworks.servicestests.R.raw.active_admin_migrated), 6450 getProfileOwnerPoliciesFile()); 6451 DpmTestUtils.writeInputStreamToFile( 6452 getRawStream(com.android.frameworks.servicestests.R.raw.profile_owner_not_migrated), 6453 getProfileOwnerFile()); 6454 assertProfileOwnershipRevertedWithFakeTransferMetadata(); 6455 } 6456 6457 @Test testRevertProfileOwnership_adminAndProfileNotMigrated()6458 public void testRevertProfileOwnership_adminAndProfileNotMigrated() throws Exception { 6459 getServices().addUser(CALLER_USER_HANDLE, 0, 6460 UserManager.USER_TYPE_PROFILE_MANAGED, UserHandle.USER_SYSTEM); 6461 DpmTestUtils.writeInputStreamToFile( 6462 getRawStream(com.android.frameworks.servicestests.R.raw.active_admin_not_migrated), 6463 getProfileOwnerPoliciesFile()); 6464 DpmTestUtils.writeInputStreamToFile( 6465 getRawStream(com.android.frameworks.servicestests.R.raw.profile_owner_not_migrated), 6466 getProfileOwnerFile()); 6467 assertProfileOwnershipRevertedWithFakeTransferMetadata(); 6468 } 6469 6470 @Test testGrantDeviceIdsAccess_notToProfileOwner()6471 public void testGrantDeviceIdsAccess_notToProfileOwner() throws Exception { 6472 setupProfileOwner(); 6473 configureContextForAccess(mContext, false); 6474 6475 assertExpectException(SecurityException.class, /* messageRegex= */ null, 6476 () -> dpm.markProfileOwnerOnOrganizationOwnedDevice(admin2)); 6477 } 6478 6479 @Test testGrantDeviceIdsAccess_notByAuthorizedCaller()6480 public void testGrantDeviceIdsAccess_notByAuthorizedCaller() throws Exception { 6481 setupProfileOwner(); 6482 configureContextForAccess(mContext, false); 6483 6484 assertExpectException(SecurityException.class, /* messageRegex= */ null, 6485 () -> dpm.markProfileOwnerOnOrganizationOwnedDevice(admin1)); 6486 } 6487 6488 @Test testGrantDeviceIdsAccess_byAuthorizedSystemCaller()6489 public void testGrantDeviceIdsAccess_byAuthorizedSystemCaller() throws Exception { 6490 setupProfileOwner(); 6491 6492 // This method will throw if the system context could not call 6493 // markProfileOwnerOfOrganizationOwnedDevice successfully. 6494 configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE); 6495 } 6496 configureContextForAccess(DpmMockContext context, boolean granted)6497 private void configureContextForAccess(DpmMockContext context, boolean granted) { 6498 when(context.spiedContext.checkCallingPermission( 6499 permission.MARK_DEVICE_ORGANIZATION_OWNED)) 6500 .thenReturn(granted ? PackageManager.PERMISSION_GRANTED 6501 : PackageManager.PERMISSION_DENIED); 6502 6503 when(getServices().userManager.getProfileParent(any())) 6504 .thenReturn(UserHandle.SYSTEM); 6505 } 6506 6507 @Test testGrantDeviceIdsAccess_byAuthorizedManagedProvisioning()6508 public void testGrantDeviceIdsAccess_byAuthorizedManagedProvisioning() throws Exception { 6509 setupProfileOwner(); 6510 6511 final long ident = mServiceContext.binder.clearCallingIdentity(); 6512 configureContextForAccess(mServiceContext, true); 6513 mServiceContext.permissions.add(permission.MARK_DEVICE_ORGANIZATION_OWNED); 6514 6515 mServiceContext.binder.callingUid = 6516 UserHandle.getUid(CALLER_USER_HANDLE, 6517 DpmMockContext.CALLER_MANAGED_PROVISIONING_UID); 6518 try { 6519 runAsCaller(mServiceContext, dpms, dpm -> { 6520 dpm.markProfileOwnerOnOrganizationOwnedDevice(admin1); 6521 }); 6522 } finally { 6523 mServiceContext.binder.restoreCallingIdentity(ident); 6524 } 6525 } 6526 6527 @Test testEnforceCallerCanRequestDeviceIdAttestation_deviceOwnerCaller()6528 public void testEnforceCallerCanRequestDeviceIdAttestation_deviceOwnerCaller() 6529 throws Exception { 6530 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 6531 setupDeviceOwner(); 6532 configureContextForAccess(mContext, false); 6533 6534 // Device owner should be allowed to request Device ID attestation. 6535 dpms.enforceCallerCanRequestDeviceIdAttestation(dpms.getCallerIdentity(admin1)); 6536 6537 mContext.binder.callingUid = DpmMockContext.ANOTHER_UID; 6538 // Another package must not be allowed to request Device ID attestation. 6539 assertExpectException(SecurityException.class, null, 6540 () -> dpms.enforceCallerCanRequestDeviceIdAttestation( 6541 dpms.getCallerIdentity(null, admin2.getPackageName()))); 6542 6543 // Another component that is not the admin must not be allowed to request Device ID 6544 // attestation. 6545 assertExpectException(SecurityException.class, null, 6546 () -> dpms.enforceCallerCanRequestDeviceIdAttestation( 6547 dpms.getCallerIdentity(admin2))); 6548 } 6549 6550 @Test testEnforceCallerCanRequestDeviceIdAttestation_profileOwnerCaller()6551 public void testEnforceCallerCanRequestDeviceIdAttestation_profileOwnerCaller() 6552 throws Exception { 6553 configureContextForAccess(mContext, false); 6554 6555 // Make sure a security exception is thrown if the device has no profile owner. 6556 assertExpectException(SecurityException.class, null, 6557 () -> dpms.enforceCallerCanRequestDeviceIdAttestation( 6558 dpms.getCallerIdentity(admin1))); 6559 6560 setupProfileOwner(); 6561 configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE); 6562 6563 // The profile owner is allowed to request Device ID attestation. 6564 mServiceContext.binder.callingUid = DpmMockContext.CALLER_UID; 6565 dpms.enforceCallerCanRequestDeviceIdAttestation(dpms.getCallerIdentity(admin1)); 6566 6567 // But not another package. 6568 mContext.binder.callingUid = DpmMockContext.ANOTHER_UID; 6569 assertExpectException(SecurityException.class, null, 6570 () -> dpms.enforceCallerCanRequestDeviceIdAttestation( 6571 dpms.getCallerIdentity(null, admin2.getPackageName()))); 6572 6573 // Or another component which is not the admin. 6574 assertExpectException(SecurityException.class, null, 6575 () -> dpms.enforceCallerCanRequestDeviceIdAttestation( 6576 dpms.getCallerIdentity(admin2, admin2.getPackageName()))); 6577 } 6578 runAsDelegatedCertInstaller(DpmRunnable action)6579 public void runAsDelegatedCertInstaller(DpmRunnable action) throws Exception { 6580 final long ident = mServiceContext.binder.clearCallingIdentity(); 6581 6582 mServiceContext.binder.callingUid = UserHandle.getUid(CALLER_USER_HANDLE, 6583 DpmMockContext.DELEGATE_CERT_INSTALLER_UID); 6584 try { 6585 runAsCaller(mServiceContext, dpms, action); 6586 } finally { 6587 mServiceContext.binder.restoreCallingIdentity(ident); 6588 } 6589 } 6590 6591 @Test testEnforceCallerCanRequestDeviceIdAttestation_delegateCaller()6592 public void testEnforceCallerCanRequestDeviceIdAttestation_delegateCaller() throws Exception { 6593 setupProfileOwner(); 6594 markDelegatedCertInstallerAsInstalled(); 6595 6596 // Configure a delegated cert installer. 6597 runAsCaller(mServiceContext, dpms, 6598 dpm -> dpm.setDelegatedScopes(admin1, DpmMockContext.DELEGATE_PACKAGE_NAME, 6599 Arrays.asList(DELEGATION_CERT_INSTALL))); 6600 6601 configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE); 6602 6603 // Make sure that the profile owner can still request Device ID attestation. 6604 mServiceContext.binder.callingUid = DpmMockContext.CALLER_UID; 6605 dpms.enforceCallerCanRequestDeviceIdAttestation(dpms.getCallerIdentity(admin1)); 6606 6607 runAsDelegatedCertInstaller(dpm -> dpms.enforceCallerCanRequestDeviceIdAttestation( 6608 dpms.getCallerIdentity(null, DpmMockContext.DELEGATE_PACKAGE_NAME))); 6609 } 6610 6611 @Test testEnforceCallerCanRequestDeviceIdAttestation_delegateCallerWithoutPermissions()6612 public void testEnforceCallerCanRequestDeviceIdAttestation_delegateCallerWithoutPermissions() 6613 throws Exception { 6614 setupProfileOwner(); 6615 markDelegatedCertInstallerAsInstalled(); 6616 6617 // Configure a delegated cert installer. 6618 runAsCaller(mServiceContext, dpms, 6619 dpm -> dpm.setDelegatedScopes(admin1, DpmMockContext.DELEGATE_PACKAGE_NAME, 6620 Arrays.asList(DELEGATION_CERT_INSTALL))); 6621 6622 assertExpectException(SecurityException.class, null, 6623 () -> dpms.enforceCallerCanRequestDeviceIdAttestation( 6624 dpms.getCallerIdentity(admin1))); 6625 6626 runAsDelegatedCertInstaller(dpm -> { 6627 assertExpectException(SecurityException.class, /* messageRegex= */ null, 6628 () -> dpms.enforceCallerCanRequestDeviceIdAttestation( 6629 dpms.getCallerIdentity(null, DpmMockContext.DELEGATE_PACKAGE_NAME))); 6630 }); 6631 } 6632 6633 @Test testGetPasswordComplexity_securityExceptionNotThrownForParentInstance()6634 public void testGetPasswordComplexity_securityExceptionNotThrownForParentInstance() { 6635 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 6636 when(getServices().packageManager.getPackagesForUid(DpmMockContext.CALLER_UID)).thenReturn( 6637 new String[0]); 6638 mServiceContext.permissions.add(permission.REQUEST_PASSWORD_COMPLEXITY); 6639 setAsProfileOwner(admin1); 6640 6641 parentDpm.getPasswordComplexity(); 6642 6643 assertThat(dpm.getPasswordComplexity()).isEqualTo(PASSWORD_COMPLEXITY_NONE); 6644 } 6645 6646 @Test testGetPasswordComplexity_illegalStateExceptionIfLocked()6647 public void testGetPasswordComplexity_illegalStateExceptionIfLocked() { 6648 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 6649 when(getServices().packageManager.getPackagesForUid(DpmMockContext.CALLER_UID)).thenReturn( 6650 new String[0]); 6651 when(getServices().userManager.isUserUnlocked(CALLER_USER_HANDLE)).thenReturn(false); 6652 assertThrows(IllegalStateException.class, () -> dpm.getPasswordComplexity()); 6653 } 6654 6655 @Test testGetPasswordComplexity_securityExceptionWithoutPermissions()6656 public void testGetPasswordComplexity_securityExceptionWithoutPermissions() { 6657 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 6658 when(getServices().packageManager.getPackagesForUid(DpmMockContext.CALLER_UID)).thenReturn( 6659 new String[0]); 6660 when(getServices().userManager.isUserUnlocked(CALLER_USER_HANDLE)).thenReturn(true); 6661 assertThrows(SecurityException.class, () -> dpm.getPasswordComplexity()); 6662 } 6663 6664 6665 @Test testGetPasswordComplexity_currentUserNoPassword()6666 public void testGetPasswordComplexity_currentUserNoPassword() { 6667 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 6668 when(getServices().packageManager.getPackagesForUid(DpmMockContext.CALLER_UID)).thenReturn( 6669 new String[0]); 6670 when(getServices().userManager.isUserUnlocked(CALLER_USER_HANDLE)).thenReturn(true); 6671 mServiceContext.permissions.add(permission.REQUEST_PASSWORD_COMPLEXITY); 6672 when(getServices().userManager.getCredentialOwnerProfile(CALLER_USER_HANDLE)) 6673 .thenReturn(CALLER_USER_HANDLE); 6674 6675 assertThat(dpm.getPasswordComplexity()).isEqualTo(PASSWORD_COMPLEXITY_NONE); 6676 } 6677 6678 @Test testGetPasswordComplexity_currentUserHasPassword()6679 public void testGetPasswordComplexity_currentUserHasPassword() { 6680 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 6681 when(getServices().packageManager.getPackagesForUid(DpmMockContext.CALLER_UID)).thenReturn( 6682 new String[0]); 6683 when(getServices().userManager.isUserUnlocked(CALLER_USER_HANDLE)).thenReturn(true); 6684 mServiceContext.permissions.add(permission.REQUEST_PASSWORD_COMPLEXITY); 6685 when(getServices().userManager.getCredentialOwnerProfile(CALLER_USER_HANDLE)) 6686 .thenReturn(CALLER_USER_HANDLE); 6687 when(getServices().lockSettingsInternal 6688 .getUserPasswordMetrics(CALLER_USER_HANDLE)) 6689 .thenReturn(computeForPasswordOrPin("asdf".getBytes(), /* isPin */ false)); 6690 6691 assertThat(dpm.getPasswordComplexity()).isEqualTo(PASSWORD_COMPLEXITY_MEDIUM); 6692 } 6693 6694 @Test testGetPasswordComplexity_unifiedChallengeReturnsParentUserPassword()6695 public void testGetPasswordComplexity_unifiedChallengeReturnsParentUserPassword() { 6696 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 6697 when(getServices().packageManager.getPackagesForUid(DpmMockContext.CALLER_UID)).thenReturn( 6698 new String[0]); 6699 when(getServices().userManager.isUserUnlocked(CALLER_USER_HANDLE)).thenReturn(true); 6700 mServiceContext.permissions.add(permission.REQUEST_PASSWORD_COMPLEXITY); 6701 6702 UserInfo parentUser = new UserInfo(); 6703 parentUser.id = CALLER_USER_HANDLE + 10; 6704 when(getServices().userManager.getCredentialOwnerProfile(CALLER_USER_HANDLE)) 6705 .thenReturn(parentUser.id); 6706 6707 when(getServices().lockSettingsInternal 6708 .getUserPasswordMetrics(CALLER_USER_HANDLE)) 6709 .thenReturn(computeForPasswordOrPin("asdf".getBytes(), /* isPin */ false)); 6710 when(getServices().lockSettingsInternal 6711 .getUserPasswordMetrics(parentUser.id)) 6712 .thenReturn(computeForPasswordOrPin("parentUser".getBytes(), /* isPin */ false)); 6713 6714 assertThat(dpm.getPasswordComplexity()).isEqualTo(PASSWORD_COMPLEXITY_HIGH); 6715 } 6716 6717 @Test testCrossProfileCalendarPackages_initiallyEmpty()6718 public void testCrossProfileCalendarPackages_initiallyEmpty() { 6719 setAsProfileOwner(admin1); 6720 final Set<String> packages = dpm.getCrossProfileCalendarPackages(admin1); 6721 assertCrossProfileCalendarPackagesEqual(packages, Collections.emptySet()); 6722 } 6723 6724 @Test testCrossProfileCalendarPackages_reopenDpms()6725 public void testCrossProfileCalendarPackages_reopenDpms() { 6726 setAsProfileOwner(admin1); 6727 dpm.setCrossProfileCalendarPackages(admin1, null); 6728 Set<String> packages = dpm.getCrossProfileCalendarPackages(admin1); 6729 assertThat(packages == null).isTrue(); 6730 initializeDpms(); 6731 packages = dpm.getCrossProfileCalendarPackages(admin1); 6732 assertThat(packages == null).isTrue(); 6733 6734 dpm.setCrossProfileCalendarPackages(admin1, Collections.emptySet()); 6735 packages = dpm.getCrossProfileCalendarPackages(admin1); 6736 assertCrossProfileCalendarPackagesEqual(packages, Collections.emptySet()); 6737 initializeDpms(); 6738 packages = dpm.getCrossProfileCalendarPackages(admin1); 6739 assertCrossProfileCalendarPackagesEqual(packages, Collections.emptySet()); 6740 6741 final String dummyPackageName = "test"; 6742 final Set<String> testPackages = new ArraySet<String>(Arrays.asList(dummyPackageName)); 6743 dpm.setCrossProfileCalendarPackages(admin1, testPackages); 6744 packages = dpm.getCrossProfileCalendarPackages(admin1); 6745 assertCrossProfileCalendarPackagesEqual(packages, testPackages); 6746 initializeDpms(); 6747 packages = dpm.getCrossProfileCalendarPackages(admin1); 6748 assertCrossProfileCalendarPackagesEqual(packages, testPackages); 6749 } 6750 assertCrossProfileCalendarPackagesEqual(Set<String> expected, Set<String> actual)6751 private void assertCrossProfileCalendarPackagesEqual(Set<String> expected, Set<String> actual) { 6752 assertThat(expected).isNotNull(); 6753 assertThat(actual).isNotNull(); 6754 assertThat(actual).containsExactlyElementsIn(expected); 6755 } 6756 6757 @Test testIsPackageAllowedToAccessCalendar_adminNotAllowed()6758 public void testIsPackageAllowedToAccessCalendar_adminNotAllowed() { 6759 setAsProfileOwner(admin1); 6760 dpm.setCrossProfileCalendarPackages(admin1, Collections.emptySet()); 6761 when(getServices().settings.settingsSecureGetIntForUser( 6762 Settings.Secure.CROSS_PROFILE_CALENDAR_ENABLED, 6763 0, CALLER_USER_HANDLE)).thenReturn(1); 6764 mContext.permissions.add(permission.INTERACT_ACROSS_USERS); 6765 6766 assertThat(dpm.isPackageAllowedToAccessCalendar("TEST_PACKAGE")).isFalse(); 6767 } 6768 6769 @Test testIsPackageAllowedToAccessCalendar_settingOff()6770 public void testIsPackageAllowedToAccessCalendar_settingOff() { 6771 final String testPackage = "TEST_PACKAGE"; 6772 setAsProfileOwner(admin1); 6773 dpm.setCrossProfileCalendarPackages(admin1, Collections.singleton(testPackage)); 6774 when(getServices().settings.settingsSecureGetIntForUser( 6775 Settings.Secure.CROSS_PROFILE_CALENDAR_ENABLED, 6776 0, CALLER_USER_HANDLE)).thenReturn(0); 6777 mContext.permissions.add(permission.INTERACT_ACROSS_USERS); 6778 6779 assertThat(dpm.isPackageAllowedToAccessCalendar(testPackage)).isFalse(); 6780 } 6781 6782 @Test testIsPackageAllowedToAccessCalendar_bothAllowed()6783 public void testIsPackageAllowedToAccessCalendar_bothAllowed() { 6784 final String testPackage = "TEST_PACKAGE"; 6785 setAsProfileOwner(admin1); 6786 dpm.setCrossProfileCalendarPackages(admin1, null); 6787 when(getServices().settings.settingsSecureGetIntForUser( 6788 Settings.Secure.CROSS_PROFILE_CALENDAR_ENABLED, 6789 0, CALLER_USER_HANDLE)).thenReturn(1); 6790 mContext.permissions.add(permission.INTERACT_ACROSS_USERS); 6791 6792 assertThat(dpm.isPackageAllowedToAccessCalendar(testPackage)).isTrue(); 6793 } 6794 6795 @Test testIsPackageAllowedToAccessCalendar_requiresPermission()6796 public void testIsPackageAllowedToAccessCalendar_requiresPermission() { 6797 final String testPackage = "TEST_PACKAGE"; 6798 6799 assertExpectException(SecurityException.class, /* messageRegex= */ null, 6800 () -> dpm.isPackageAllowedToAccessCalendar(testPackage)); 6801 } 6802 6803 @Test testIsPackageAllowedToAccessCalendar_samePackageAndSameUser_noPermissionRequired()6804 public void testIsPackageAllowedToAccessCalendar_samePackageAndSameUser_noPermissionRequired() 6805 throws Exception { 6806 final String testPackage = "TEST_PACKAGE"; 6807 setAsProfileOwner(admin1); 6808 dpm.setCrossProfileCalendarPackages(admin1, null); 6809 when(getServices().settings.settingsSecureGetIntForUser( 6810 Settings.Secure.CROSS_PROFILE_CALENDAR_ENABLED, 6811 0, CALLER_USER_HANDLE)).thenReturn(1); 6812 doReturn(mContext.binder.callingUid) 6813 .when(getServices().packageManager).getPackageUidAsUser( 6814 eq(testPackage), 6815 anyInt()); 6816 6817 assertThat(dpm.isPackageAllowedToAccessCalendar(testPackage)).isTrue(); 6818 } 6819 6820 @Test testSetUserControlDisabledPackages_asDO()6821 public void testSetUserControlDisabledPackages_asDO() throws Exception { 6822 final List<String> testPackages = new ArrayList<>(); 6823 testPackages.add("package_1"); 6824 testPackages.add("package_2"); 6825 mServiceContext.permissions.add(permission.MANAGE_DEVICE_ADMINS); 6826 setDeviceOwner(); 6827 6828 dpm.setUserControlDisabledPackages(admin1, testPackages); 6829 6830 verify(getServices().packageManagerInternal) 6831 .setDeviceOwnerProtectedPackages(admin1.getPackageName(), testPackages); 6832 assertThat(dpm.getUserControlDisabledPackages(admin1)).isEqualTo(testPackages); 6833 } 6834 6835 @Test testSetUserControlDisabledPackages_failingAsPO()6836 public void testSetUserControlDisabledPackages_failingAsPO() { 6837 final List<String> testPackages = new ArrayList<>(); 6838 testPackages.add("package_1"); 6839 testPackages.add("package_2"); 6840 mServiceContext.permissions.add(permission.MANAGE_DEVICE_ADMINS); 6841 setAsProfileOwner(admin1); 6842 6843 assertExpectException(SecurityException.class, /* messageRegex= */ null, 6844 () -> dpm.setUserControlDisabledPackages(admin1, testPackages)); 6845 assertExpectException(SecurityException.class, /* messageRegex= */ null, 6846 () -> dpm.getUserControlDisabledPackages(admin1)); 6847 } 6848 configureProfileOwnerOfOrgOwnedDevice(ComponentName who, int userId)6849 private void configureProfileOwnerOfOrgOwnedDevice(ComponentName who, int userId) { 6850 final long ident = mServiceContext.binder.clearCallingIdentity(); 6851 mServiceContext.binder.callingUid = UserHandle.getUid(userId, DpmMockContext.SYSTEM_UID); 6852 6853 configureContextForAccess(mServiceContext, true); 6854 runAsCaller(mServiceContext, dpms, dpm -> { 6855 dpm.markProfileOwnerOnOrganizationOwnedDevice(who); 6856 }); 6857 mServiceContext.binder.restoreCallingIdentity(ident); 6858 } 6859 6860 @Test testGetCrossProfilePackages_notSet_returnsEmpty()6861 public void testGetCrossProfilePackages_notSet_returnsEmpty() { 6862 setAsProfileOwner(admin1); 6863 assertThat(dpm.getCrossProfilePackages(admin1).isEmpty()).isTrue(); 6864 } 6865 6866 @Test testGetCrossProfilePackages_notSet_dpmsReinitialized_returnsEmpty()6867 public void testGetCrossProfilePackages_notSet_dpmsReinitialized_returnsEmpty() { 6868 setAsProfileOwner(admin1); 6869 6870 initializeDpms(); 6871 6872 assertThat(dpm.getCrossProfilePackages(admin1).isEmpty()).isTrue(); 6873 } 6874 6875 @Test testGetCrossProfilePackages_whenSet_returnsEqual()6876 public void testGetCrossProfilePackages_whenSet_returnsEqual() { 6877 setAsProfileOwner(admin1); 6878 Set<String> packages = Collections.singleton("TEST_PACKAGE"); 6879 6880 dpm.setCrossProfilePackages(admin1, packages); 6881 6882 assertThat(dpm.getCrossProfilePackages(admin1)).isEqualTo(packages); 6883 } 6884 6885 @Test testGetCrossProfilePackages_whenSet_dpmsReinitialized_returnsEqual()6886 public void testGetCrossProfilePackages_whenSet_dpmsReinitialized_returnsEqual() { 6887 setAsProfileOwner(admin1); 6888 Set<String> packages = Collections.singleton("TEST_PACKAGE"); 6889 6890 dpm.setCrossProfilePackages(admin1, packages); 6891 initializeDpms(); 6892 6893 assertThat(dpm.getCrossProfilePackages(admin1)).isEqualTo(packages); 6894 } 6895 6896 @Test testGetAllCrossProfilePackages_notSet_returnsEmpty()6897 public void testGetAllCrossProfilePackages_notSet_returnsEmpty() throws Exception { 6898 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS); 6899 addManagedProfile(admin1, mServiceContext.binder.callingUid, admin1); 6900 mContext.packageName = admin1.getPackageName(); 6901 6902 setCrossProfileAppsList(); 6903 setVendorCrossProfileAppsList(); 6904 6905 assertThat(dpm.getAllCrossProfilePackages().isEmpty()).isTrue(); 6906 } 6907 6908 @Test testGetAllCrossProfilePackages_notSet_dpmsReinitialized_returnsEmpty()6909 public void testGetAllCrossProfilePackages_notSet_dpmsReinitialized_returnsEmpty() 6910 throws Exception { 6911 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS); 6912 addManagedProfile(admin1, mServiceContext.binder.callingUid, admin1); 6913 mContext.packageName = admin1.getPackageName(); 6914 6915 setCrossProfileAppsList(); 6916 setVendorCrossProfileAppsList(); 6917 initializeDpms(); 6918 6919 assertThat(dpm.getAllCrossProfilePackages().isEmpty()).isTrue(); 6920 } 6921 6922 @Test testGetAllCrossProfilePackages_whenSet_returnsCombinedSet()6923 public void testGetAllCrossProfilePackages_whenSet_returnsCombinedSet() throws Exception { 6924 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS); 6925 addManagedProfile(admin1, mServiceContext.binder.callingUid, admin1); 6926 final Set<String> packages = Sets.newSet("TEST_PACKAGE", "TEST_COMMON_PACKAGE"); 6927 mContext.packageName = admin1.getPackageName(); 6928 6929 dpm.setCrossProfilePackages(admin1, packages); 6930 setCrossProfileAppsList("TEST_DEFAULT_PACKAGE", "TEST_COMMON_PACKAGE"); 6931 setVendorCrossProfileAppsList("TEST_VENDOR_DEFAULT_PACKAGE"); 6932 6933 assertThat(dpm.getAllCrossProfilePackages()).containsExactly( 6934 "TEST_PACKAGE", "TEST_DEFAULT_PACKAGE", "TEST_COMMON_PACKAGE", 6935 "TEST_VENDOR_DEFAULT_PACKAGE"); 6936 } 6937 6938 @Test testGetAllCrossProfilePackages_whenSet_dpmsReinitialized_returnsCombinedSet()6939 public void testGetAllCrossProfilePackages_whenSet_dpmsReinitialized_returnsCombinedSet() 6940 throws Exception { 6941 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS); 6942 addManagedProfile(admin1, mServiceContext.binder.callingUid, admin1); 6943 final Set<String> packages = Sets.newSet("TEST_PACKAGE", "TEST_COMMON_PACKAGE"); 6944 mContext.packageName = admin1.getPackageName(); 6945 6946 dpm.setCrossProfilePackages(admin1, packages); 6947 setCrossProfileAppsList("TEST_DEFAULT_PACKAGE", "TEST_COMMON_PACKAGE"); 6948 setVendorCrossProfileAppsList("TEST_VENDOR_DEFAULT_PACKAGE"); 6949 initializeDpms(); 6950 6951 assertThat(dpm.getAllCrossProfilePackages()).containsExactly( 6952 "TEST_PACKAGE", "TEST_DEFAULT_PACKAGE", "TEST_COMMON_PACKAGE", 6953 "TEST_VENDOR_DEFAULT_PACKAGE"); 6954 } 6955 6956 @Test testGetDefaultCrossProfilePackages_noPackagesSet_returnsEmpty()6957 public void testGetDefaultCrossProfilePackages_noPackagesSet_returnsEmpty() { 6958 setCrossProfileAppsList(); 6959 setVendorCrossProfileAppsList(); 6960 6961 assertThat(dpm.getDefaultCrossProfilePackages()).isEmpty(); 6962 } 6963 6964 @Test testGetDefaultCrossProfilePackages_packagesSet_returnsCombinedSet()6965 public void testGetDefaultCrossProfilePackages_packagesSet_returnsCombinedSet() { 6966 setCrossProfileAppsList("TEST_DEFAULT_PACKAGE", "TEST_COMMON_PACKAGE"); 6967 setVendorCrossProfileAppsList("TEST_VENDOR_DEFAULT_PACKAGE"); 6968 6969 assertThat(dpm.getDefaultCrossProfilePackages()).containsExactly( 6970 "TEST_DEFAULT_PACKAGE", "TEST_COMMON_PACKAGE", "TEST_VENDOR_DEFAULT_PACKAGE"); 6971 } 6972 6973 @Test testSetCommonCriteriaMode_asDeviceOwner()6974 public void testSetCommonCriteriaMode_asDeviceOwner() throws Exception { 6975 setDeviceOwner(); 6976 6977 assertThat(dpm.isCommonCriteriaModeEnabled(admin1)).isFalse(); 6978 assertThat(dpm.isCommonCriteriaModeEnabled(null)).isFalse(); 6979 6980 dpm.setCommonCriteriaModeEnabled(admin1, true); 6981 6982 assertThat(dpm.isCommonCriteriaModeEnabled(admin1)).isTrue(); 6983 assertThat(dpm.isCommonCriteriaModeEnabled(null)).isTrue(); 6984 } 6985 6986 @Test testSetCommonCriteriaMode_asPoOfOrgOwnedDevice()6987 public void testSetCommonCriteriaMode_asPoOfOrgOwnedDevice() throws Exception { 6988 final int managedProfileUserId = 15; 6989 final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); 6990 addManagedProfile(admin1, managedProfileAdminUid, admin1); 6991 configureProfileOwnerOfOrgOwnedDevice(admin1, managedProfileUserId); 6992 mContext.binder.callingUid = managedProfileAdminUid; 6993 6994 assertThat(dpm.isCommonCriteriaModeEnabled(admin1)).isFalse(); 6995 assertThat(dpm.isCommonCriteriaModeEnabled(null)).isFalse(); 6996 6997 dpm.setCommonCriteriaModeEnabled(admin1, true); 6998 6999 assertThat(dpm.isCommonCriteriaModeEnabled(admin1)).isTrue(); 7000 assertThat(dpm.isCommonCriteriaModeEnabled(null)).isTrue(); 7001 } 7002 7003 @Test testCanProfileOwnerResetPasswordWhenLocked_nonDirectBootAwarePo()7004 public void testCanProfileOwnerResetPasswordWhenLocked_nonDirectBootAwarePo() 7005 throws Exception { 7006 setDeviceEncryptionPerUser(); 7007 setupProfileOwner(); 7008 setupPasswordResetToken(); 7009 7010 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 7011 assertWithMessage("po is not direct boot aware") 7012 .that(dpm.canProfileOwnerResetPasswordWhenLocked(CALLER_USER_HANDLE)).isFalse(); 7013 } 7014 7015 @Test testCanProfileOwnerResetPasswordWhenLocked_noActiveToken()7016 public void testCanProfileOwnerResetPasswordWhenLocked_noActiveToken() throws Exception { 7017 setDeviceEncryptionPerUser(); 7018 setupProfileOwner(); 7019 makeAdmin1DirectBootAware(); 7020 7021 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 7022 assertWithMessage("po doesn't have an active password reset token") 7023 .that(dpm.canProfileOwnerResetPasswordWhenLocked(CALLER_USER_HANDLE)).isFalse(); 7024 } 7025 7026 @Test testCanProfileOwnerResetPasswordWhenLocked_nonFbeDevice()7027 public void testCanProfileOwnerResetPasswordWhenLocked_nonFbeDevice() throws Exception { 7028 setupProfileOwner(); 7029 makeAdmin1DirectBootAware(); 7030 setupPasswordResetToken(); 7031 7032 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 7033 assertWithMessage("device is not FBE") 7034 .that(dpm.canProfileOwnerResetPasswordWhenLocked(CALLER_USER_HANDLE)).isFalse(); 7035 } 7036 7037 @Test testCanProfileOwnerResetPasswordWhenLocked()7038 public void testCanProfileOwnerResetPasswordWhenLocked() throws Exception { 7039 setDeviceEncryptionPerUser(); 7040 setupProfileOwner(); 7041 makeAdmin1DirectBootAware(); 7042 setupPasswordResetToken(); 7043 7044 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 7045 assertWithMessage("direct boot aware po with active password reset token") 7046 .that(dpm.canProfileOwnerResetPasswordWhenLocked(CALLER_USER_HANDLE)).isTrue(); 7047 } 7048 setupPasswordResetToken()7049 private void setupPasswordResetToken() { 7050 final byte[] token = new byte[32]; 7051 final long handle = 123456; 7052 7053 when(getServices().lockPatternUtils 7054 .addEscrowToken(eq(token), eq(CALLER_USER_HANDLE), 7055 nullable(EscrowTokenStateChangeCallback.class))) 7056 .thenReturn(handle); 7057 7058 dpm.setResetPasswordToken(admin1, token); 7059 7060 when(getServices().lockPatternUtils 7061 .isEscrowTokenActive(eq(handle), eq(CALLER_USER_HANDLE))) 7062 .thenReturn(true); 7063 7064 assertWithMessage("failed to activate token").that(dpm.isResetPasswordTokenActive(admin1)) 7065 .isTrue(); 7066 } 7067 makeAdmin1DirectBootAware()7068 private void makeAdmin1DirectBootAware() 7069 throws PackageManager.NameNotFoundException, android.os.RemoteException { 7070 Mockito.reset(getServices().ipackageManager); 7071 7072 final ApplicationInfo ai = DpmTestUtils.cloneParcelable( 7073 mRealTestContext.getPackageManager().getApplicationInfo( 7074 admin1.getPackageName(), 7075 PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS)); 7076 ai.privateFlags = PRIVATE_FLAG_DIRECT_BOOT_AWARE; 7077 7078 doReturn(ai).when(getServices().ipackageManager).getApplicationInfo( 7079 eq(admin1.getPackageName()), 7080 anyInt(), 7081 eq(CALLER_USER_HANDLE)); 7082 } 7083 setDeviceEncryptionPerUser()7084 private void setDeviceEncryptionPerUser() { 7085 when(getServices().storageManager.isFileBasedEncryptionEnabled()).thenReturn(true); 7086 } 7087 setCrossProfileAppsList(String... packages)7088 private void setCrossProfileAppsList(String... packages) { 7089 when(mContext.getResources() 7090 .getStringArray(eq(R.array.cross_profile_apps))) 7091 .thenReturn(packages); 7092 } 7093 setVendorCrossProfileAppsList(String... packages)7094 private void setVendorCrossProfileAppsList(String... packages) { 7095 when(mContext.getResources() 7096 .getStringArray(eq(R.array.vendor_cross_profile_apps))) 7097 .thenReturn(packages); 7098 } 7099 7100 @Test testSetAccountTypesWithManagementDisabledOnManagedProfile()7101 public void testSetAccountTypesWithManagementDisabledOnManagedProfile() throws Exception { 7102 setupProfileOwner(); 7103 7104 final String accountType = "com.example.account.type"; 7105 int originalUid = mContext.binder.callingUid; 7106 dpm.setAccountManagementDisabled(admin1, accountType, true); 7107 assertThat(dpm.getAccountTypesWithManagementDisabled()).asList().containsExactly( 7108 accountType); 7109 mContext.binder.callingUid = DpmMockContext.ANOTHER_UID; 7110 assertThat(dpm.getAccountTypesWithManagementDisabled()).isEmpty(); 7111 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 7112 assertThat(dpm.getAccountTypesWithManagementDisabled()).isEmpty(); 7113 7114 mContext.binder.callingUid = originalUid; 7115 dpm.setAccountManagementDisabled(admin1, accountType, false); 7116 assertThat(dpm.getAccountTypesWithManagementDisabled()).isEmpty(); 7117 } 7118 7119 @Test testSetAccountTypesWithManagementDisabledOnOrgOwnedManagedProfile()7120 public void testSetAccountTypesWithManagementDisabledOnOrgOwnedManagedProfile() 7121 throws Exception { 7122 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS); 7123 7124 final int managedProfileUserId = 15; 7125 final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); 7126 7127 addManagedProfile(admin1, managedProfileAdminUid, admin1); 7128 mContext.binder.callingUid = managedProfileAdminUid; 7129 7130 configureProfileOwnerOfOrgOwnedDevice(admin1, managedProfileUserId); 7131 7132 int originalUid = mContext.binder.callingUid; 7133 final String accountType = "com.example.account.type"; 7134 dpm.getParentProfileInstance(admin1).setAccountManagementDisabled(admin1, accountType, 7135 true); 7136 assertThat(dpm.getAccountTypesWithManagementDisabled()).isEmpty(); 7137 mContext.binder.callingUid = DpmMockContext.ANOTHER_UID; 7138 assertThat(dpm.getAccountTypesWithManagementDisabled()).asList().containsExactly( 7139 accountType); 7140 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 7141 assertThat(dpm.getAccountTypesWithManagementDisabled()).asList().containsExactly( 7142 accountType); 7143 7144 mContext.binder.callingUid = originalUid; 7145 dpm.getParentProfileInstance(admin1).setAccountManagementDisabled(admin1, accountType, 7146 false); 7147 mContext.binder.callingUid = DpmMockContext.ANOTHER_UID; 7148 assertThat(dpm.getAccountTypesWithManagementDisabled()).isEmpty(); 7149 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 7150 assertThat(dpm.getAccountTypesWithManagementDisabled()).isEmpty(); 7151 } 7152 7153 /** 7154 * Tests the case when the user doesn't turn the profile on in time, verifies that the user is 7155 * warned with a notification and then the apps get suspended. 7156 */ 7157 @Test testMaximumProfileTimeOff_profileOffTimeExceeded()7158 public void testMaximumProfileTimeOff_profileOffTimeExceeded() throws Exception { 7159 prepareMocksForSetMaximumProfileTimeOff(); 7160 7161 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 7162 dpm.setManagedProfileMaximumTimeOff(admin1, PROFILE_OFF_TIMEOUT); 7163 7164 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 7165 // The profile is running, neither alarm nor notification should be posted. 7166 verify(getServices().alarmManager, never()) 7167 .set(anyInt(), anyLong(), any(PendingIntent.class)); 7168 verify(getServices().notificationManager, never()) 7169 .notify(anyInt(), any(Notification.class)); 7170 // Apps shouldn't be suspended. 7171 verifyZeroInteractions(getServices().ipackageManager); 7172 clearInvocations(getServices().alarmManager); 7173 7174 setUserUnlocked(CALLER_USER_HANDLE, false); 7175 sendBroadcastWithUser(dpms, Intent.ACTION_USER_STOPPED, CALLER_USER_HANDLE); 7176 7177 // Verify the alarm was scheduled for time when the warning should be shown. 7178 verify(getServices().alarmManager, times(1)) 7179 .set(anyInt(), eq(PROFILE_OFF_WARNING_TIME), any()); 7180 // But still no notification should be posted at this point. 7181 verify(getServices().notificationManager, never()) 7182 .notify(anyInt(), any(Notification.class)); 7183 // Apps shouldn't be suspended. 7184 verifyZeroInteractions(getServices().ipackageManager); 7185 clearInvocations(getServices().alarmManager); 7186 7187 // Pretend the alarm went off. 7188 dpms.mMockInjector.setSystemCurrentTimeMillis(PROFILE_OFF_WARNING_TIME + 10); 7189 sendBroadcastWithUser(dpms, ACTION_PROFILE_OFF_DEADLINE, CALLER_USER_HANDLE); 7190 7191 // Verify the alarm was scheduled for the actual deadline this time. 7192 verify(getServices().alarmManager, times(1)).set(anyInt(), eq(PROFILE_OFF_DEADLINE), any()); 7193 // Now the user should see a warning notification. 7194 verify(getServices().notificationManager, times(1)) 7195 .notify(anyInt(), argThat(hasExtra(EXTRA_TITLE, PROFILE_OFF_SUSPENSION_TITLE, 7196 EXTRA_TEXT, PROFILE_OFF_SUSPENSION_SOON_TEXT))); 7197 // Apps shouldn't be suspended yet. 7198 verifyZeroInteractions(getServices().ipackageManager); 7199 clearInvocations(getServices().alarmManager); 7200 clearInvocations(getServices().notificationManager); 7201 7202 // Pretend the alarm went off. 7203 dpms.mMockInjector.setSystemCurrentTimeMillis(PROFILE_OFF_DEADLINE + 10); 7204 sendBroadcastWithUser(dpms, ACTION_PROFILE_OFF_DEADLINE, CALLER_USER_HANDLE); 7205 7206 // Verify the alarm was not set. 7207 verifyZeroInteractions(getServices().alarmManager); 7208 // Now the user should see a notification about suspended apps. 7209 verify(getServices().notificationManager, times(1)) 7210 .notify(anyInt(), argThat(hasExtra(EXTRA_TITLE, PROFILE_OFF_SUSPENSION_TITLE, 7211 EXTRA_TEXT, PROFILE_OFF_SUSPENSION_TEXT))); 7212 // Verify that the apps are suspended. 7213 verify(getServices().ipackageManager, times(1)).setPackagesSuspendedAsUser( 7214 any(), eq(true), any(), any(), any(), any(), anyInt()); 7215 } 7216 7217 /** 7218 * Tests the case when the user turns the profile back on long before the deadline (> 1 day). 7219 */ 7220 @Test testMaximumProfileTimeOff_turnOnBeforeWarning()7221 public void testMaximumProfileTimeOff_turnOnBeforeWarning() throws Exception { 7222 prepareMocksForSetMaximumProfileTimeOff(); 7223 7224 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 7225 dpm.setManagedProfileMaximumTimeOff(admin1, PROFILE_OFF_TIMEOUT); 7226 7227 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 7228 setUserUnlocked(CALLER_USER_HANDLE, false); 7229 sendBroadcastWithUser(dpms, Intent.ACTION_USER_STOPPED, CALLER_USER_HANDLE); 7230 clearInvocations(getServices().alarmManager); 7231 setUserUnlocked(CALLER_USER_HANDLE, true); 7232 sendBroadcastWithUser(dpms, Intent.ACTION_USER_UNLOCKED, CALLER_USER_HANDLE); 7233 7234 // Verify that the alarm got discharged. 7235 verify(getServices().alarmManager, times(1)).cancel((PendingIntent) null); 7236 } 7237 7238 /** 7239 * Tests the case when the user turns the profile back on after the warning notification. 7240 */ 7241 @Test testMaximumProfileTimeOff_turnOnAfterWarning()7242 public void testMaximumProfileTimeOff_turnOnAfterWarning() throws Exception { 7243 prepareMocksForSetMaximumProfileTimeOff(); 7244 7245 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 7246 dpm.setManagedProfileMaximumTimeOff(admin1, PROFILE_OFF_TIMEOUT); 7247 7248 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 7249 setUserUnlocked(CALLER_USER_HANDLE, false); 7250 sendBroadcastWithUser(dpms, Intent.ACTION_USER_STOPPED, CALLER_USER_HANDLE); 7251 7252 // Pretend the alarm went off. 7253 dpms.mMockInjector.setSystemCurrentTimeMillis(PROFILE_OFF_WARNING_TIME + 10); 7254 sendBroadcastWithUser(dpms, ACTION_PROFILE_OFF_DEADLINE, CALLER_USER_HANDLE); 7255 7256 clearInvocations(getServices().alarmManager); 7257 clearInvocations(getServices().notificationManager); 7258 setUserUnlocked(CALLER_USER_HANDLE, true); 7259 sendBroadcastWithUser(dpms, Intent.ACTION_USER_UNLOCKED, CALLER_USER_HANDLE); 7260 7261 // Verify that the alarm got discharged. 7262 verify(getServices().alarmManager, times(1)).cancel((PendingIntent) null); 7263 // Verify that the notification is removed. 7264 verify(getServices().notificationManager, times(1)) 7265 .cancel(eq(SystemMessageProto.SystemMessage.NOTE_PERSONAL_APPS_SUSPENDED)); 7266 } 7267 7268 /** 7269 * Tests the case when the user turns the profile back on when the apps are already suspended. 7270 */ 7271 @Test testMaximumProfileTimeOff_turnOnAfterDeadline()7272 public void testMaximumProfileTimeOff_turnOnAfterDeadline() throws Exception { 7273 prepareMocksForSetMaximumProfileTimeOff(); 7274 7275 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 7276 dpm.setManagedProfileMaximumTimeOff(admin1, PROFILE_OFF_TIMEOUT); 7277 7278 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 7279 setUserUnlocked(CALLER_USER_HANDLE, false); 7280 sendBroadcastWithUser(dpms, Intent.ACTION_USER_STOPPED, CALLER_USER_HANDLE); 7281 7282 // Pretend the alarm went off after the deadline. 7283 dpms.mMockInjector.setSystemCurrentTimeMillis(PROFILE_OFF_DEADLINE + 10); 7284 sendBroadcastWithUser(dpms, ACTION_PROFILE_OFF_DEADLINE, CALLER_USER_HANDLE); 7285 7286 clearInvocations(getServices().alarmManager); 7287 clearInvocations(getServices().notificationManager); 7288 clearInvocations(getServices().ipackageManager); 7289 7290 // Pretend the user clicked on the "apps suspended" notification to turn the profile on. 7291 sendBroadcastWithUser(dpms, ACTION_TURN_PROFILE_ON_NOTIFICATION, CALLER_USER_HANDLE); 7292 // Verify that the profile is turned on. 7293 verify(getServices().userManager, times(1)) 7294 .requestQuietModeEnabled(eq(false), eq(UserHandle.of(CALLER_USER_HANDLE))); 7295 7296 setUserUnlocked(CALLER_USER_HANDLE, true); 7297 sendBroadcastWithUser(dpms, Intent.ACTION_USER_UNLOCKED, CALLER_USER_HANDLE); 7298 7299 // Verify that the notification is removed (at this point DPC should show it). 7300 verify(getServices().notificationManager, times(1)) 7301 .cancel(eq(SystemMessageProto.SystemMessage.NOTE_PERSONAL_APPS_SUSPENDED)); 7302 // Verify that the apps are NOT unsuspeded. 7303 verify(getServices().ipackageManager, never()).setPackagesSuspendedAsUser( 7304 any(), eq(false), any(), any(), any(), any(), anyInt()); 7305 // Verify that DPC is invoked to check policy compliance. 7306 verify(mContext.spiedContext).startActivityAsUser( 7307 MockUtils.checkIntentAction(ACTION_CHECK_POLICY_COMPLIANCE), 7308 MockUtils.checkUserHandle(CALLER_USER_HANDLE)); 7309 7310 // Verify that correct suspension reason is reported to the DPC. 7311 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 7312 assertThat(dpm.getPersonalAppsSuspendedReasons(admin1)) 7313 .isEqualTo(DevicePolicyManager.PERSONAL_APPS_SUSPENDED_PROFILE_TIMEOUT); 7314 7315 // Verify that rolling time back doesn't change the status. 7316 dpms.mMockInjector.setSystemCurrentTimeMillis(PROFILE_OFF_START); 7317 assertThat(dpm.getPersonalAppsSuspendedReasons(admin1)) 7318 .isEqualTo(DevicePolicyManager.PERSONAL_APPS_SUSPENDED_PROFILE_TIMEOUT); 7319 } 7320 7321 @Test testSetRequiredPasswordComplexity_UnauthorizedCallersOnDO()7322 public void testSetRequiredPasswordComplexity_UnauthorizedCallersOnDO() throws Exception { 7323 assumeDeprecatedPasswordApisSupported(); 7324 7325 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 7326 setupDeviceOwner(); 7327 // DO must be able to set it. 7328 dpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_LOW); 7329 // But not on the parent DPM. 7330 assertExpectException(IllegalArgumentException.class, null, 7331 () -> parentDpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_LOW)); 7332 // Another package must not be allowed to set password complexity. 7333 mContext.binder.callingUid = DpmMockContext.ANOTHER_UID; 7334 assertExpectException(SecurityException.class, null, 7335 () -> dpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_LOW)); 7336 } 7337 7338 @Test testSetRequiredPasswordComplexity_UnauthorizedCallersOnPO()7339 public void testSetRequiredPasswordComplexity_UnauthorizedCallersOnPO() throws Exception { 7340 assumeDeprecatedPasswordApisSupported(); 7341 7342 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 7343 setupProfileOwner(); 7344 // PO must be able to set it. 7345 dpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_LOW); 7346 // And on the parent profile DPM instance. 7347 parentDpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_LOW); 7348 // Another package must not be allowed to set password complexity. 7349 mContext.binder.callingUid = DpmMockContext.ANOTHER_UID; 7350 assertExpectException(SecurityException.class, null, 7351 () -> dpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_LOW)); 7352 } 7353 7354 @Test testSetRequiredPasswordComplexity_validValuesOnly()7355 public void testSetRequiredPasswordComplexity_validValuesOnly() throws Exception { 7356 assumeDeprecatedPasswordApisSupported(); 7357 7358 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 7359 setupProfileOwner(); 7360 7361 // Cannot set value other than password_complexity none/low/medium/high 7362 assertExpectException(IllegalArgumentException.class, null, () -> 7363 dpm.setRequiredPasswordComplexity(-1)); 7364 assertExpectException(IllegalArgumentException.class, null, () -> 7365 dpm.setRequiredPasswordComplexity(7)); 7366 assertExpectException(IllegalArgumentException.class, null, () -> 7367 dpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_HIGH + 1)); 7368 7369 final Set<Integer> allowedModes = Set.of(PASSWORD_COMPLEXITY_NONE, PASSWORD_COMPLEXITY_LOW, 7370 PASSWORD_COMPLEXITY_MEDIUM, PASSWORD_COMPLEXITY_HIGH); 7371 for (int complexity : allowedModes) { 7372 // Ensure exception is not thrown. 7373 dpm.setRequiredPasswordComplexity(complexity); 7374 } 7375 } 7376 7377 @Test testSetRequiredPasswordComplexity_setAndGet()7378 public void testSetRequiredPasswordComplexity_setAndGet() throws Exception { 7379 assumeDeprecatedPasswordApisSupported(); 7380 7381 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 7382 setupProfileOwner(); 7383 7384 final Set<Integer> allowedModes = Set.of(PASSWORD_COMPLEXITY_NONE, PASSWORD_COMPLEXITY_LOW, 7385 PASSWORD_COMPLEXITY_MEDIUM, PASSWORD_COMPLEXITY_HIGH); 7386 for (int complexity : allowedModes) { 7387 dpm.setRequiredPasswordComplexity(complexity); 7388 assertThat(dpm.getRequiredPasswordComplexity()).isEqualTo(complexity); 7389 } 7390 } 7391 7392 @Test testSetRequiredPasswordComplexityOnParent_setAndGet()7393 public void testSetRequiredPasswordComplexityOnParent_setAndGet() throws Exception { 7394 assumeDeprecatedPasswordApisSupported(); 7395 7396 final int managedProfileUserId = 15; 7397 final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); 7398 7399 addManagedProfile(admin1, managedProfileAdminUid, admin1); 7400 mContext.binder.callingUid = managedProfileAdminUid; 7401 7402 final Set<Integer> allowedModes = Set.of(PASSWORD_COMPLEXITY_NONE, PASSWORD_COMPLEXITY_LOW, 7403 PASSWORD_COMPLEXITY_MEDIUM, PASSWORD_COMPLEXITY_HIGH); 7404 for (int complexity : allowedModes) { 7405 dpm.getParentProfileInstance(admin1).setRequiredPasswordComplexity(complexity); 7406 assertThat(dpm.getParentProfileInstance(admin1).getRequiredPasswordComplexity()) 7407 .isEqualTo(complexity); 7408 assertThat(dpm.getRequiredPasswordComplexity()).isEqualTo(PASSWORD_COMPLEXITY_NONE); 7409 } 7410 } 7411 7412 @Test testSetRequiredPasswordComplexity_isSufficient()7413 public void testSetRequiredPasswordComplexity_isSufficient() throws Exception { 7414 assumeDeprecatedPasswordApisSupported(); 7415 7416 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID; 7417 mContext.packageName = admin1.getPackageName(); 7418 setupDeviceOwner(); 7419 7420 dpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_HIGH); 7421 assertThat(dpm.getRequiredPasswordComplexity()).isEqualTo(PASSWORD_COMPLEXITY_HIGH); 7422 when(getServices().packageManager.getPackagesForUid( 7423 DpmMockContext.CALLER_SYSTEM_USER_UID)).thenReturn(new String[0]); 7424 mServiceContext.permissions.add(permission.REQUEST_PASSWORD_COMPLEXITY); 7425 assertThat(dpm.getPasswordComplexity()).isEqualTo(PASSWORD_COMPLEXITY_NONE); 7426 7427 reset(mContext.spiedContext); 7428 PasswordMetrics passwordMetricsNoSymbols = computeForPasswordOrPin( 7429 "1234".getBytes(), /* isPin */ true); 7430 setActivePasswordState(passwordMetricsNoSymbols); 7431 assertThat(dpm.getPasswordComplexity()).isEqualTo(PASSWORD_COMPLEXITY_LOW); 7432 assertThat(dpm.isActivePasswordSufficient()).isFalse(); 7433 7434 reset(mContext.spiedContext); 7435 passwordMetricsNoSymbols = computeForPasswordOrPin( 7436 "84125312943a".getBytes(), /* isPin */ false); 7437 setActivePasswordState(passwordMetricsNoSymbols); 7438 assertThat(dpm.getPasswordComplexity()).isEqualTo(PASSWORD_COMPLEXITY_HIGH); 7439 // using isActivePasswordSufficient 7440 assertThat(dpm.isActivePasswordSufficient()).isTrue(); 7441 } 7442 7443 @Test testSetRequiredPasswordComplexity_resetBySettingQuality()7444 public void testSetRequiredPasswordComplexity_resetBySettingQuality() throws Exception { 7445 assumeDeprecatedPasswordApisSupported(); 7446 7447 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 7448 setupProfileOwner(); 7449 7450 // Test that calling setPasswordQuality resets complexity to none. 7451 dpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_HIGH); 7452 assertThat(dpm.getRequiredPasswordComplexity()).isEqualTo(PASSWORD_COMPLEXITY_HIGH); 7453 dpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX); 7454 assertThat(dpm.getRequiredPasswordComplexity()).isEqualTo(PASSWORD_COMPLEXITY_NONE); 7455 } 7456 7457 @Test testSetRequiredPasswordComplexity_overridesQuality()7458 public void testSetRequiredPasswordComplexity_overridesQuality() throws Exception { 7459 assumeDeprecatedPasswordApisSupported(); 7460 7461 mContext.binder.callingUid = DpmMockContext.CALLER_UID; 7462 setupProfileOwner(); 7463 7464 // Test that calling setRequiredPasswordComplexity resets password quality. 7465 dpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX); 7466 assertThat(dpm.getPasswordQuality(admin1)).isEqualTo( 7467 DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX); 7468 dpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_HIGH); 7469 assertThat(dpm.getPasswordQuality(admin1)).isEqualTo( 7470 DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED); 7471 } 7472 7473 @Test testSetRequiredPasswordComplexityFailsWithQualityOnParent()7474 public void testSetRequiredPasswordComplexityFailsWithQualityOnParent() throws Exception { 7475 assumeDeprecatedPasswordApisSupported(); 7476 7477 final int managedProfileUserId = CALLER_USER_HANDLE; 7478 final int managedProfileAdminUid = 7479 UserHandle.getUid(managedProfileUserId, DpmMockContext.SYSTEM_UID); 7480 mContext.binder.callingUid = managedProfileAdminUid; 7481 addManagedProfile(admin1, managedProfileAdminUid, admin1, VERSION_CODES.R); 7482 7483 parentDpm.setPasswordQuality(admin1, DevicePolicyManager.PASSWORD_QUALITY_COMPLEX); 7484 7485 assertThrows(IllegalStateException.class, 7486 () -> dpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_HIGH)); 7487 } 7488 7489 @Test testSetQualityOnParentFailsWithComplexityOnProfile()7490 public void testSetQualityOnParentFailsWithComplexityOnProfile() throws Exception { 7491 assumeDeprecatedPasswordApisSupported(); 7492 7493 final int managedProfileUserId = CALLER_USER_HANDLE; 7494 final int managedProfileAdminUid = 7495 UserHandle.getUid(managedProfileUserId, DpmMockContext.SYSTEM_UID); 7496 mContext.binder.callingUid = managedProfileAdminUid; 7497 addManagedProfile(admin1, managedProfileAdminUid, admin1, VERSION_CODES.R); 7498 7499 dpm.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_HIGH); 7500 7501 assertThrows(IllegalStateException.class, 7502 () -> parentDpm.setPasswordQuality(admin1, 7503 DevicePolicyManager.PASSWORD_QUALITY_COMPLEX)); 7504 } 7505 7506 @Test testSetDeviceOwnerType_throwsExceptionWhenCallerNotAuthorized()7507 public void testSetDeviceOwnerType_throwsExceptionWhenCallerNotAuthorized() { 7508 assertThrows(SecurityException.class, 7509 () -> dpm.setDeviceOwnerType(admin1, DEVICE_OWNER_TYPE_DEFAULT)); 7510 } 7511 7512 @Test testSetDeviceOwnerType_throwsExceptionWhenThereIsNoDeviceOwner()7513 public void testSetDeviceOwnerType_throwsExceptionWhenThereIsNoDeviceOwner() { 7514 mContext.binder.clearCallingIdentity(); 7515 assertThrows(IllegalStateException.class, 7516 () -> dpm.setDeviceOwnerType(admin1, DEVICE_OWNER_TYPE_DEFAULT)); 7517 } 7518 7519 @Test testSetDeviceOwnerType_throwsExceptionWhenNotAsDeviceOwnerAdmin()7520 public void testSetDeviceOwnerType_throwsExceptionWhenNotAsDeviceOwnerAdmin() throws Exception { 7521 setDeviceOwner(); 7522 7523 assertThrows(IllegalStateException.class, 7524 () -> dpm.setDeviceOwnerType(admin2, DEVICE_OWNER_TYPE_FINANCED)); 7525 } 7526 7527 @Test testSetDeviceOwnerType_asDeviceOwner_toFinancedDevice()7528 public void testSetDeviceOwnerType_asDeviceOwner_toFinancedDevice() throws Exception { 7529 setDeviceOwner(); 7530 7531 dpm.setDeviceOwnerType(admin1, DEVICE_OWNER_TYPE_FINANCED); 7532 7533 int returnedDeviceOwnerType = dpm.getDeviceOwnerType(admin1); 7534 assertThat(dpms.mOwners.hasDeviceOwner()).isTrue(); 7535 assertThat(returnedDeviceOwnerType).isEqualTo(DEVICE_OWNER_TYPE_FINANCED); 7536 7537 initializeDpms(); 7538 7539 returnedDeviceOwnerType = dpm.getDeviceOwnerType(admin1); 7540 assertThat(dpms.mOwners.hasDeviceOwner()).isTrue(); 7541 assertThat(returnedDeviceOwnerType).isEqualTo(DEVICE_OWNER_TYPE_FINANCED); 7542 } 7543 7544 @Test testSetDeviceOwnerType_asDeviceOwner_throwsExceptionWhenSetDeviceOwnerTypeAgain()7545 public void testSetDeviceOwnerType_asDeviceOwner_throwsExceptionWhenSetDeviceOwnerTypeAgain() 7546 throws Exception { 7547 setDeviceOwner(); 7548 7549 dpm.setDeviceOwnerType(admin1, DEVICE_OWNER_TYPE_FINANCED); 7550 7551 int returnedDeviceOwnerType = dpm.getDeviceOwnerType(admin1); 7552 assertThat(dpms.mOwners.hasDeviceOwner()).isTrue(); 7553 assertThat(returnedDeviceOwnerType).isEqualTo(DEVICE_OWNER_TYPE_FINANCED); 7554 7555 assertThrows(IllegalStateException.class, 7556 () -> dpm.setDeviceOwnerType(admin1, DEVICE_OWNER_TYPE_DEFAULT)); 7557 } 7558 7559 @Test testGetDeviceOwnerType_throwsExceptionWhenThereIsNoDeviceOwner()7560 public void testGetDeviceOwnerType_throwsExceptionWhenThereIsNoDeviceOwner() { 7561 assertThrows(IllegalStateException.class, () -> dpm.getDeviceOwnerType(admin1)); 7562 } 7563 7564 @Test testGetDeviceOwnerType_throwsExceptionWhenNotAsDeviceOwnerAdmin()7565 public void testGetDeviceOwnerType_throwsExceptionWhenNotAsDeviceOwnerAdmin() throws Exception { 7566 setDeviceOwner(); 7567 7568 assertThrows(IllegalStateException.class, () -> dpm.getDeviceOwnerType(admin2)); 7569 } 7570 7571 @Test testSetUsbDataSignalingEnabled_noDeviceOwnerOrPoOfOrgOwnedDevice()7572 public void testSetUsbDataSignalingEnabled_noDeviceOwnerOrPoOfOrgOwnedDevice() { 7573 assertThrows(SecurityException.class, 7574 () -> dpm.setUsbDataSignalingEnabled(true)); 7575 } 7576 7577 @Test testSetUsbDataSignalingEnabled_asDeviceOwner()7578 public void testSetUsbDataSignalingEnabled_asDeviceOwner() throws Exception { 7579 setDeviceOwner(); 7580 when(getServices().usbManager.enableUsbDataSignal(false)).thenReturn(true); 7581 when(getServices().usbManager.getUsbHalVersion()).thenReturn(UsbManager.USB_HAL_V1_3); 7582 7583 assertThat(dpm.isUsbDataSignalingEnabled()).isTrue(); 7584 7585 dpm.setUsbDataSignalingEnabled(false); 7586 7587 assertThat(dpm.isUsbDataSignalingEnabled()).isFalse(); 7588 } 7589 7590 @Test testIsUsbDataSignalingEnabledForUser_systemUser()7591 public void testIsUsbDataSignalingEnabledForUser_systemUser() throws Exception { 7592 when(getServices().usbManager.enableUsbDataSignal(false)).thenReturn(true); 7593 when(getServices().usbManager.getUsbHalVersion()).thenReturn(UsbManager.USB_HAL_V1_3); 7594 setDeviceOwner(); 7595 dpm.setUsbDataSignalingEnabled(false); 7596 mContext.binder.callingUid = DpmMockContext.SYSTEM_UID; 7597 7598 assertThat(dpm.isUsbDataSignalingEnabledForUser(UserHandle.myUserId())).isFalse(); 7599 } 7600 7601 @Test testSetUsbDataSignalingEnabled_asPoOfOrgOwnedDevice()7602 public void testSetUsbDataSignalingEnabled_asPoOfOrgOwnedDevice() throws Exception { 7603 final int managedProfileUserId = 15; 7604 final int managedProfileAdminUid = UserHandle.getUid(managedProfileUserId, 19436); 7605 addManagedProfile(admin1, managedProfileAdminUid, admin1); 7606 configureProfileOwnerOfOrgOwnedDevice(admin1, managedProfileUserId); 7607 mContext.binder.callingUid = managedProfileAdminUid; 7608 when(getServices().usbManager.enableUsbDataSignal(false)).thenReturn(true); 7609 when(getServices().usbManager.getUsbHalVersion()).thenReturn(UsbManager.USB_HAL_V1_3); 7610 7611 assertThat(dpm.isUsbDataSignalingEnabled()).isTrue(); 7612 7613 dpm.setUsbDataSignalingEnabled(false); 7614 7615 assertThat(dpm.isUsbDataSignalingEnabled()).isFalse(); 7616 } 7617 7618 @Test testCanUsbDataSignalingBeDisabled_canBeDisabled()7619 public void testCanUsbDataSignalingBeDisabled_canBeDisabled() throws Exception { 7620 when(getServices().usbManager.getUsbHalVersion()).thenReturn(UsbManager.USB_HAL_V1_3); 7621 7622 assertThat(dpm.canUsbDataSignalingBeDisabled()).isTrue(); 7623 } 7624 7625 @Test testCanUsbDataSignalingBeDisabled_cannotBeDisabled()7626 public void testCanUsbDataSignalingBeDisabled_cannotBeDisabled() throws Exception { 7627 setDeviceOwner(); 7628 when(getServices().usbManager.getUsbHalVersion()).thenReturn(UsbManager.USB_HAL_V1_2); 7629 7630 assertThat(dpm.canUsbDataSignalingBeDisabled()).isFalse(); 7631 assertThrows(IllegalStateException.class, 7632 () -> dpm.setUsbDataSignalingEnabled(true)); 7633 } 7634 7635 @Test testSetUsbDataSignalingEnabled_noChangeToActiveAdmin()7636 public void testSetUsbDataSignalingEnabled_noChangeToActiveAdmin() 7637 throws Exception { 7638 setDeviceOwner(); 7639 when(getServices().usbManager.getUsbHalVersion()).thenReturn(UsbManager.USB_HAL_V1_3); 7640 boolean enabled = dpm.isUsbDataSignalingEnabled(); 7641 7642 dpm.setUsbDataSignalingEnabled(true); 7643 7644 assertThat(dpm.isUsbDataSignalingEnabled()).isEqualTo(enabled); 7645 } 7646 7647 @Test testGetPolicyExemptApps_noPermission()7648 public void testGetPolicyExemptApps_noPermission() { 7649 assertThrows(SecurityException.class, () -> dpm.getPolicyExemptApps()); 7650 } 7651 7652 @Test testGetPolicyExemptApps_empty()7653 public void testGetPolicyExemptApps_empty() { 7654 grantManageDeviceAdmins(); 7655 mockPolicyExemptApps(); 7656 mockVendorPolicyExemptApps(); 7657 7658 assertThat(dpm.getPolicyExemptApps()).isEmpty(); 7659 } 7660 7661 @Test testGetPolicyExemptApps_baseOnly()7662 public void testGetPolicyExemptApps_baseOnly() { 7663 grantManageDeviceAdmins(); 7664 mockPolicyExemptApps("foo"); 7665 mockVendorPolicyExemptApps(); 7666 7667 assertThat(dpm.getPolicyExemptApps()).containsExactly("foo"); 7668 } 7669 7670 @Test testGetPolicyExemptApps_vendorOnly()7671 public void testGetPolicyExemptApps_vendorOnly() { 7672 grantManageDeviceAdmins(); 7673 mockPolicyExemptApps(); 7674 mockVendorPolicyExemptApps("bar"); 7675 7676 assertThat(dpm.getPolicyExemptApps()).containsExactly("bar"); 7677 } 7678 7679 @Test testGetPolicyExemptApps_baseAndVendor()7680 public void testGetPolicyExemptApps_baseAndVendor() { 7681 grantManageDeviceAdmins(); 7682 mockPolicyExemptApps("4", "23", "15", "42", "8"); 7683 mockVendorPolicyExemptApps("16", "15", "4"); 7684 7685 assertThat(dpm.getPolicyExemptApps()).containsExactly("4", "8", "15", "16", "23", "42"); 7686 } 7687 7688 @Test testSetGlobalPrivateDnsModeOpportunistic_asDeviceOwner()7689 public void testSetGlobalPrivateDnsModeOpportunistic_asDeviceOwner() throws Exception { 7690 setDeviceOwner(); 7691 // setUp() adds a secondary user for CALLER_USER_HANDLE. Remove it as otherwise the 7692 // feature is disabled because there are non-affiliated secondary users. 7693 getServices().removeUser(CALLER_USER_HANDLE); 7694 clearInvocations(getServices().settings); 7695 7696 int result = dpm.setGlobalPrivateDnsModeOpportunistic(admin1); 7697 7698 assertThat(result).isEqualTo(PRIVATE_DNS_SET_NO_ERROR); 7699 } 7700 7701 @Test testSetGlobalPrivateDnsModeOpportunistic_hasUnaffiliatedUsers()7702 public void testSetGlobalPrivateDnsModeOpportunistic_hasUnaffiliatedUsers() throws Exception { 7703 setDeviceOwner(); 7704 setAsProfileOwner(admin2); 7705 7706 assertThrows(SecurityException.class, 7707 () -> dpm.setGlobalPrivateDnsModeOpportunistic(admin1)); 7708 } 7709 7710 @Test testSetRecommendedGlobalProxy_asDeviceOwner()7711 public void testSetRecommendedGlobalProxy_asDeviceOwner() throws Exception { 7712 setDeviceOwner(); 7713 // setUp() adds a secondary user for CALLER_USER_HANDLE. Remove it as otherwise the 7714 // feature is disabled because there are non-affiliated secondary users. 7715 getServices().removeUser(CALLER_USER_HANDLE); 7716 7717 dpm.setRecommendedGlobalProxy(admin1, null); 7718 7719 verify(getServices().connectivityManager).setGlobalProxy(null); 7720 } 7721 7722 @Test testSetRecommendedGlobalProxy_hasUnaffiliatedUsers()7723 public void testSetRecommendedGlobalProxy_hasUnaffiliatedUsers() throws Exception { 7724 setDeviceOwner(); 7725 setAsProfileOwner(admin2); 7726 7727 assertThrows(SecurityException.class, () -> dpm.setRecommendedGlobalProxy(admin1, null)); 7728 } 7729 7730 @Test testSetAlwaysOnVpnPackage_clearsAdminVpn()7731 public void testSetAlwaysOnVpnPackage_clearsAdminVpn() throws Exception { 7732 setDeviceOwner(); 7733 7734 when(getServices().vpnManager 7735 .setAlwaysOnVpnPackageForUser(anyInt(), any(), anyBoolean(), any())) 7736 .thenReturn(true); 7737 7738 // Set VPN package to admin package. 7739 dpm.setAlwaysOnVpnPackage(admin1, admin1.getPackageName(), false, null); 7740 7741 verify(getServices().vpnManager).setAlwaysOnVpnPackageForUser( 7742 UserHandle.USER_SYSTEM, admin1.getPackageName(), false, null); 7743 7744 // Clear VPN package. 7745 dpm.setAlwaysOnVpnPackage(admin1, null, false, null); 7746 7747 // Change should be propagated to VpnManager 7748 verify(getServices().vpnManager).setAlwaysOnVpnPackageForUser( 7749 UserHandle.USER_SYSTEM, null, false, null); 7750 // The package should lose authorization to start VPN. 7751 verify(getServices().appOpsManager).setMode(OP_ACTIVATE_VPN, 7752 DpmMockContext.CALLER_SYSTEM_USER_UID, admin1.getPackageName(), MODE_DEFAULT); 7753 } 7754 7755 @Test testSetAlwaysOnVpnPackage_doesntKillUserVpn()7756 public void testSetAlwaysOnVpnPackage_doesntKillUserVpn() throws Exception { 7757 setDeviceOwner(); 7758 7759 when(getServices().vpnManager 7760 .setAlwaysOnVpnPackageForUser(anyInt(), any(), anyBoolean(), any())) 7761 .thenReturn(true); 7762 7763 // this time it shouldn't go into VpnManager anymore. 7764 dpm.setAlwaysOnVpnPackage(admin1, null, false, null); 7765 7766 verifyNoMoreInteractions(getServices().vpnManager); 7767 verifyNoMoreInteractions(getServices().appOpsManager); 7768 } 7769 7770 @Test testDisallowConfigVpn_clearsUserVpn()7771 public void testDisallowConfigVpn_clearsUserVpn() throws Exception { 7772 final String userVpnPackage = "org.some.vpn.servcie"; 7773 final int userVpnUid = 20374; 7774 7775 setDeviceOwner(); 7776 7777 setupVpnAuthorization(userVpnPackage, userVpnUid); 7778 7779 simulateRestrictionAdded(UserManager.DISALLOW_CONFIG_VPN); 7780 7781 verify(getServices().vpnManager).setAlwaysOnVpnPackageForUser( 7782 UserHandle.USER_SYSTEM, null, false, null); 7783 verify(getServices().appOpsManager).setMode(OP_ACTIVATE_VPN, 7784 userVpnUid, userVpnPackage, MODE_DEFAULT); 7785 } 7786 7787 @Test testDisallowConfigVpn_doesntKillAdminVpn()7788 public void testDisallowConfigVpn_doesntKillAdminVpn() throws Exception { 7789 setDeviceOwner(); 7790 7791 when(getServices().vpnManager 7792 .setAlwaysOnVpnPackageForUser(anyInt(), any(), anyBoolean(), any())) 7793 .thenReturn(true); 7794 7795 // Set VPN package to admin package. 7796 dpm.setAlwaysOnVpnPackage(admin1, admin1.getPackageName(), false, null); 7797 setupVpnAuthorization(admin1.getPackageName(), DpmMockContext.CALLER_SYSTEM_USER_UID); 7798 clearInvocations(getServices().vpnManager); 7799 7800 simulateRestrictionAdded(UserManager.DISALLOW_CONFIG_VPN); 7801 7802 // Admin-set package should remain always-on and should retain its authorization. 7803 verifyNoMoreInteractions(getServices().vpnManager); 7804 verify(getServices().appOpsManager, never()).setMode(OP_ACTIVATE_VPN, 7805 DpmMockContext.CALLER_SYSTEM_USER_UID, admin1.getPackageName(), MODE_DEFAULT); 7806 } 7807 7808 @Test testGetOrganizationNameForUser_calledByNonPrivilegedApp_throwsException()7809 public void testGetOrganizationNameForUser_calledByNonPrivilegedApp_throwsException() { 7810 assertExpectException(SecurityException.class, "Calling identity is not authorized", 7811 () -> dpm.getOrganizationNameForUser(UserHandle.USER_SYSTEM)); 7812 } 7813 setupVpnAuthorization(String userVpnPackage, int userVpnUid)7814 private void setupVpnAuthorization(String userVpnPackage, int userVpnUid) { 7815 final AppOpsManager.PackageOps vpnOp = new AppOpsManager.PackageOps(userVpnPackage, 7816 userVpnUid, List.of(new AppOpsManager.OpEntry( 7817 OP_ACTIVATE_VPN, MODE_ALLOWED, Collections.emptyMap()))); 7818 when(getServices().appOpsManager.getPackagesForOps(any(int[].class))) 7819 .thenReturn(List.of(vpnOp)); 7820 } 7821 simulateRestrictionAdded(String restriction)7822 private void simulateRestrictionAdded(String restriction) { 7823 RestrictionsListener listener = new RestrictionsListener( 7824 mServiceContext, getServices().userManagerInternal, dpms); 7825 7826 final Bundle newRestrictions = new Bundle(); 7827 newRestrictions.putBoolean(restriction, true); 7828 listener.onUserRestrictionsChanged(UserHandle.USER_SYSTEM, newRestrictions, new Bundle()); 7829 } 7830 setUserUnlocked(int userHandle, boolean unlocked)7831 private void setUserUnlocked(int userHandle, boolean unlocked) { 7832 when(getServices().userManager.isUserUnlocked(eq(userHandle))).thenReturn(unlocked); 7833 } 7834 prepareMocksForSetMaximumProfileTimeOff()7835 private void prepareMocksForSetMaximumProfileTimeOff() throws Exception { 7836 addManagedProfile(admin1, DpmMockContext.CALLER_UID, admin1); 7837 configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE); 7838 7839 when(getServices().userManager.isUserUnlocked()).thenReturn(true); 7840 7841 doReturn(Collections.singletonList(new ResolveInfo())) 7842 .when(getServices().packageManager).queryIntentActivitiesAsUser( 7843 any(Intent.class), anyInt(), eq(CALLER_USER_HANDLE)); 7844 7845 dpms.mMockInjector.setSystemCurrentTimeMillis(PROFILE_OFF_START); 7846 // To allow creation of Notification via Notification.Builder 7847 mContext.applicationInfo = mRealTestContext.getApplicationInfo(); 7848 7849 // Setup resources to render notification titles and texts. 7850 when(mServiceContext.resources 7851 .getString(R.string.personal_apps_suspension_title)) 7852 .thenReturn(PROFILE_OFF_SUSPENSION_TITLE); 7853 when(mServiceContext.resources 7854 .getString(R.string.personal_apps_suspension_text)) 7855 .thenReturn(PROFILE_OFF_SUSPENSION_TEXT); 7856 when(mServiceContext.resources 7857 .getString(eq(R.string.personal_apps_suspension_soon_text), 7858 anyString(), anyString(), anyInt())) 7859 .thenReturn(PROFILE_OFF_SUSPENSION_SOON_TEXT); 7860 7861 // Make locale available for date formatting: 7862 when(mServiceContext.resources.getConfiguration()) 7863 .thenReturn(mRealTestContext.getResources().getConfiguration()); 7864 7865 clearInvocations(getServices().ipackageManager); 7866 } 7867 hasExtra(String... extras)7868 private static Matcher<Notification> hasExtra(String... extras) { 7869 assertWithMessage("Odd number of extra key-values").that(extras.length % 2).isEqualTo(0); 7870 return new BaseMatcher<Notification>() { 7871 @Override 7872 public boolean matches(Object item) { 7873 final Notification notification = (Notification) item; 7874 for (int i = 0; i < extras.length / 2; i++) { 7875 if (!extras[i * 2 + 1].equals(notification.extras.getString(extras[i * 2]))) { 7876 return false; 7877 } 7878 } 7879 return true; 7880 } 7881 @Override 7882 public void describeTo(Description description) { 7883 description.appendText("Notification{"); 7884 for (int i = 0; i < extras.length / 2; i++) { 7885 if (i > 0) { 7886 description.appendText(","); 7887 } 7888 description.appendText(extras[i * 2] + "=\"" + extras[i * 2 + 1] + "\""); 7889 } 7890 description.appendText("}"); 7891 } 7892 }; 7893 } 7894 7895 // admin1 is the outgoing DPC, adminAnotherPackage is the incoming one. 7896 private void assertDeviceOwnershipRevertedWithFakeTransferMetadata() throws Exception { 7897 writeFakeTransferMetadataFile(UserHandle.USER_SYSTEM, 7898 TransferOwnershipMetadataManager.ADMIN_TYPE_DEVICE_OWNER); 7899 7900 final long ident = mServiceContext.binder.clearCallingIdentity(); 7901 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID); 7902 setUpPackageManagerForFakeAdmin(adminAnotherPackage, 7903 DpmMockContext.CALLER_SYSTEM_USER_UID, admin1); 7904 // To simulate a reboot, we just reinitialize dpms and call systemReady 7905 initializeDpms(); 7906 7907 assertThat(dpm.isDeviceOwnerApp(admin1.getPackageName())).isTrue(); 7908 assertThat(dpm.isDeviceOwnerApp(adminAnotherPackage.getPackageName())).isFalse(); 7909 assertThat(dpm.isAdminActive(adminAnotherPackage)).isFalse(); 7910 assertThat(dpm.isAdminActive(admin1)).isTrue(); 7911 assertThat(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName())).isTrue(); 7912 assertThat(dpm.getDeviceOwnerComponentOnCallingUser()).isEqualTo(admin1); 7913 7914 assertThat(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName())).isTrue(); 7915 assertThat(dpm.getDeviceOwnerComponentOnAnyUser()).isEqualTo(admin1); 7916 assertThat(dpm.getDeviceOwnerUserId()).isEqualTo(UserHandle.USER_SYSTEM); 7917 assertThat(getMockTransferMetadataManager().metadataFileExists()).isFalse(); 7918 7919 mServiceContext.binder.restoreCallingIdentity(ident); 7920 } 7921 7922 // admin1 is the outgoing DPC, adminAnotherPackage is the incoming one. 7923 private void assertProfileOwnershipRevertedWithFakeTransferMetadata() throws Exception { 7924 writeFakeTransferMetadataFile(CALLER_USER_HANDLE, 7925 TransferOwnershipMetadataManager.ADMIN_TYPE_PROFILE_OWNER); 7926 7927 int uid = UserHandle.getUid(CALLER_USER_HANDLE, 7928 DpmMockContext.CALLER_SYSTEM_USER_UID); 7929 setUpPackageManagerForAdmin(admin1, uid); 7930 setUpPackageManagerForFakeAdmin(adminAnotherPackage, uid, admin1); 7931 // To simulate a reboot, we just reinitialize dpms and call systemReady 7932 initializeDpms(); 7933 7934 assertThat(dpm.isProfileOwnerApp(admin1.getPackageName())).isTrue(); 7935 assertThat(dpm.isAdminActive(admin1)).isTrue(); 7936 assertThat(dpm.isProfileOwnerApp(adminAnotherPackage.getPackageName())).isFalse(); 7937 assertThat(dpm.isAdminActive(adminAnotherPackage)).isFalse(); 7938 assertThat(admin1).isEqualTo(dpm.getProfileOwnerAsUser(CALLER_USER_HANDLE)); 7939 assertThat(getMockTransferMetadataManager().metadataFileExists()).isFalse(); 7940 } 7941 7942 private void writeFakeTransferMetadataFile(int callerUserHandle, String adminType) { 7943 TransferOwnershipMetadataManager metadataManager = getMockTransferMetadataManager(); 7944 metadataManager.deleteMetadataFile(); 7945 7946 final TransferOwnershipMetadataManager.Metadata metadata = 7947 new TransferOwnershipMetadataManager.Metadata( 7948 admin1.flattenToString(), adminAnotherPackage.flattenToString(), 7949 callerUserHandle, 7950 adminType); 7951 metadataManager.saveMetadataFile(metadata); 7952 } 7953 7954 private File getDeviceOwnerFile() { 7955 return dpms.mOwners.getDeviceOwnerFile(); 7956 } 7957 7958 private File getProfileOwnerFile() { 7959 return dpms.mOwners.getProfileOwnerFile(CALLER_USER_HANDLE); 7960 } 7961 7962 private File getProfileOwnerPoliciesFile() { 7963 File parentDir = dpms.mMockInjector.environmentGetUserSystemDirectory( 7964 CALLER_USER_HANDLE); 7965 return getPoliciesFile(parentDir); 7966 } 7967 7968 private File getDeviceOwnerPoliciesFile() { 7969 return getPoliciesFile(getServices().systemUserDataDir); 7970 } 7971 7972 private File getPoliciesFile(File parentDir) { 7973 return new File(parentDir, "device_policies.xml"); 7974 } 7975 7976 private void setUserSetupCompleteForUser(boolean isUserSetupComplete, int userhandle) { 7977 when(getServices().settings.settingsSecureGetIntForUser(Settings.Secure.USER_SETUP_COMPLETE, 0, 7978 userhandle)).thenReturn(isUserSetupComplete ? 1 : 0); 7979 dpms.notifyChangeToContentObserver( 7980 Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE), userhandle); 7981 } 7982 7983 private void assertProvisioningAllowed(String action, boolean expected) { 7984 assertWithMessage("isProvisioningAllowed(%s) returning unexpected result", action) 7985 .that(dpm.isProvisioningAllowed(action)).isEqualTo(expected); 7986 } 7987 7988 private void assertProvisioningAllowed(String action, boolean expected, String packageName, 7989 int uid) { 7990 final String previousPackageName = mContext.packageName; 7991 final int previousUid = mMockContext.binder.callingUid; 7992 7993 // Call assertProvisioningAllowed with the packageName / uid passed as arguments. 7994 mContext.packageName = packageName; 7995 mMockContext.binder.callingUid = uid; 7996 assertProvisioningAllowed(action, expected); 7997 7998 // Set the previous package name / calling uid to go back to the initial state. 7999 mContext.packageName = previousPackageName; 8000 mMockContext.binder.callingUid = previousUid; 8001 } 8002 8003 private void assertCheckProvisioningPreCondition(String action, int provisioningCondition) { 8004 assertCheckProvisioningPreCondition(action, admin1.getPackageName(), provisioningCondition); 8005 } 8006 8007 private void assertCheckProvisioningPreCondition( 8008 String action, String packageName, int provisioningCondition) { 8009 assertWithMessage("checkProvisioningPreCondition(%s, %s) returning unexpected result", 8010 action, packageName).that(dpm.checkProvisioningPreCondition(action, packageName)) 8011 .isEqualTo(provisioningCondition); 8012 } 8013 8014 /** 8015 * Setup a managed profile with the specified admin and its uid. 8016 * @param admin ComponentName that's visible to the test code, which doesn't have to exist. 8017 * @param adminUid uid of the admin package. 8018 * @param copyFromAdmin package information for {@code admin} will be built based on this 8019 * component's information. 8020 * @param appTargetSdk admin's target SDK level 8021 */ 8022 private void addManagedProfile( 8023 ComponentName admin, int adminUid, ComponentName copyFromAdmin, int appTargetSdk) 8024 throws Exception { 8025 final int userId = UserHandle.getUserId(adminUid); 8026 getServices().addUser(userId, 0, UserManager.USER_TYPE_PROFILE_MANAGED, 8027 UserHandle.USER_SYSTEM); 8028 mContext.callerPermissions.addAll(OWNER_SETUP_PERMISSIONS); 8029 setUpPackageManagerForFakeAdmin(admin, adminUid, /* enabledSetting= */ null, 8030 appTargetSdk, copyFromAdmin); 8031 dpm.setActiveAdmin(admin, false, userId); 8032 assertThat(dpm.setProfileOwner(admin, null, userId)).isTrue(); 8033 mContext.callerPermissions.removeAll(OWNER_SETUP_PERMISSIONS); 8034 } 8035 8036 /** 8037 * Same as {@code addManagedProfile} above, except using development API level as the API 8038 * level of the admin. 8039 */ 8040 private void addManagedProfile( 8041 ComponentName admin, int adminUid, ComponentName copyFromAdmin) throws Exception { 8042 addManagedProfile(admin, adminUid, copyFromAdmin, VERSION_CODES.CUR_DEVELOPMENT); 8043 } 8044 8045 /** 8046 * Convert String[] to StringParceledListSlice. 8047 */ 8048 private static StringParceledListSlice asSlice(String[] s) { 8049 return new StringParceledListSlice(Arrays.asList(s)); 8050 } 8051 8052 private void grantManageDeviceAdmins() { 8053 Log.d(TAG, "Granting " + permission.MANAGE_DEVICE_ADMINS); 8054 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS); 8055 } 8056 8057 private void mockPolicyExemptApps(String... apps) { 8058 Log.d(TAG, "Mocking R.array.policy_exempt_apps to return " + Arrays.toString(apps)); 8059 when(mContext.resources.getStringArray(R.array.policy_exempt_apps)).thenReturn(apps); 8060 } 8061 8062 private void mockVendorPolicyExemptApps(String... apps) { 8063 Log.d(TAG, "Mocking R.array.vendor_policy_exempt_apps to return " + Arrays.toString(apps)); 8064 when(mContext.resources.getStringArray(R.array.vendor_policy_exempt_apps)).thenReturn(apps); 8065 } 8066 8067 private void mockEmptyPolicyExemptApps() { 8068 when(mContext.getResources().getStringArray(R.array.policy_exempt_apps)) 8069 .thenReturn(new String[0]); 8070 when(mContext.getResources().getStringArray(R.array.vendor_policy_exempt_apps)) 8071 .thenReturn(new String[0]); 8072 } 8073 8074 private boolean isDeprecatedPasswordApisSupported() { 8075 return !mIsAutomotive; 8076 } 8077 8078 private void assumeDeprecatedPasswordApisSupported() { 8079 assumeTrue("device doesn't support deprecated password APIs", 8080 isDeprecatedPasswordApisSupported()); 8081 } 8082 } 8083