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