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