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