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