DevicePolicyManagerTest.java revision 4f7e1fc9af698e08576c9beadef872f5c4ea04a8
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 */
16package com.android.server.devicepolicy;
17
18import static android.os.UserManagerInternal.CAMERA_DISABLED_GLOBALLY;
19import static android.os.UserManagerInternal.CAMERA_DISABLED_LOCALLY;
20import static android.os.UserManagerInternal.CAMERA_NOT_DISABLED;
21
22import android.Manifest.permission;
23import android.app.Activity;
24import android.app.Notification;
25import android.app.NotificationManager;
26import android.app.admin.DeviceAdminReceiver;
27import android.app.admin.DevicePolicyManager;
28import android.app.admin.DevicePolicyManagerInternal;
29import android.content.BroadcastReceiver;
30import android.content.ComponentName;
31import android.content.Context;
32import android.content.Intent;
33import android.content.ServiceConnection;
34import android.content.pm.ApplicationInfo;
35import android.content.pm.PackageInfo;
36import android.content.pm.PackageManager;
37import android.content.pm.ParceledListSlice;
38import android.content.res.Resources;
39import android.graphics.Color;
40import android.net.IIpConnectivityMetrics;
41import android.net.Uri;
42import android.content.pm.UserInfo;
43import android.net.wifi.WifiInfo;
44import android.os.Build.VERSION_CODES;
45import android.os.Bundle;
46import android.os.IBinder;
47import android.os.Process;
48import android.os.UserHandle;
49import android.os.UserManager;
50import android.os.UserManagerInternal;
51import android.provider.Settings;
52import android.telephony.TelephonyManager;
53import android.test.MoreAsserts;
54import android.test.suitebuilder.annotation.SmallTest;
55import android.util.ArraySet;
56import android.util.Pair;
57
58import com.android.internal.R;
59import com.android.internal.util.ParcelableString;
60import com.android.internal.widget.LockPatternUtils;
61import com.android.server.LocalServices;
62import com.android.server.SystemService;
63import com.android.server.pm.UserRestrictionsUtils;
64
65import org.hamcrest.BaseMatcher;
66import org.hamcrest.Description;
67import org.mockito.invocation.InvocationOnMock;
68import org.mockito.stubbing.Answer;
69
70import java.util.ArrayList;
71import java.util.Arrays;
72import java.util.Collections;
73import java.util.HashMap;
74import java.util.List;
75import java.util.Map;
76import java.util.Set;
77import java.util.concurrent.TimeUnit;
78
79import static android.app.admin.DevicePolicyManager.DELEGATION_APP_RESTRICTIONS;
80import static android.app.admin.DevicePolicyManager.DELEGATION_CERT_INSTALL;
81
82import static org.mockito.Matchers.any;
83import static org.mockito.Matchers.anyInt;
84import static org.mockito.Matchers.anyLong;
85import static org.mockito.Matchers.anyObject;
86import static org.mockito.Matchers.anyString;
87import static org.mockito.Matchers.argThat;
88import static org.mockito.Matchers.eq;
89import static org.mockito.Matchers.isNull;
90import static org.mockito.Mockito.atLeast;
91import static org.mockito.Mockito.doAnswer;
92import static org.mockito.Mockito.doReturn;
93import static org.mockito.Mockito.mock;
94import static org.mockito.Mockito.never;
95import static org.mockito.Mockito.reset;
96import static org.mockito.Mockito.timeout;
97import static org.mockito.Mockito.times;
98import static org.mockito.Mockito.verify;
99import static org.mockito.Mockito.verifyZeroInteractions;
100import static org.mockito.Mockito.when;
101
102/**
103 * Tests for DevicePolicyManager( and DevicePolicyManagerService).
104 * You can run them via:
105 m FrameworksServicesTests &&
106 adb install \
107   -r ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk &&
108 adb shell am instrument -e class com.android.server.devicepolicy.DevicePolicyManagerTest \
109   -w com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
110
111 (mmma frameworks/base/services/tests/servicestests/ for non-ninja build)
112 *
113 * , or:
114 * runtest -c com.android.server.devicepolicy.DevicePolicyManagerTest frameworks-services
115 */
116@SmallTest
117public class DevicePolicyManagerTest extends DpmTestBase {
118    private static final List<String> OWNER_SETUP_PERMISSIONS = Arrays.asList(
119            permission.MANAGE_DEVICE_ADMINS, permission.MANAGE_PROFILE_AND_DEVICE_OWNERS,
120            permission.MANAGE_USERS, permission.INTERACT_ACROSS_USERS_FULL);
121
122    private DpmMockContext mContext;
123    public DevicePolicyManager dpm;
124    public DevicePolicyManagerServiceTestable dpms;
125
126    @Override
127    protected void setUp() throws Exception {
128        super.setUp();
129
130        mContext = getContext();
131
132        when(mContext.packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN)))
133                .thenReturn(true);
134
135        // By default, pretend all users are running and unlocked.
136        when(mContext.userManager.isUserUnlocked(anyInt())).thenReturn(true);
137
138        initializeDpms();
139
140        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID);
141        setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID);
142        setUpPackageManagerForAdmin(admin3, DpmMockContext.CALLER_UID);
143        setUpPackageManagerForAdmin(adminNoPerm, DpmMockContext.CALLER_UID);
144
145        setUpUserManager();
146    }
147
148    private void initializeDpms() {
149        // Need clearCallingIdentity() to pass permission checks.
150        final long ident = mContext.binder.clearCallingIdentity();
151        try {
152            LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
153
154            dpms = new DevicePolicyManagerServiceTestable(mContext, dataDir);
155
156            dpms.systemReady(SystemService.PHASE_LOCK_SETTINGS_READY);
157            dpms.systemReady(SystemService.PHASE_BOOT_COMPLETED);
158
159            dpm = new DevicePolicyManagerTestable(mContext, dpms);
160        } finally {
161            mContext.binder.restoreCallingIdentity(ident);
162        }
163    }
164
165    private void setUpUserManager() {
166        // Emulate UserManager.set/getApplicationRestriction().
167        final Map<Pair<String, UserHandle>, Bundle> appRestrictions = new HashMap<>();
168
169        // UM.setApplicationRestrictions() will save to appRestrictions.
170        doAnswer(new Answer<Void>() {
171            @Override
172            public Void answer(InvocationOnMock invocation) throws Throwable {
173                String pkg = (String) invocation.getArguments()[0];
174                Bundle bundle = (Bundle) invocation.getArguments()[1];
175                UserHandle user = (UserHandle) invocation.getArguments()[2];
176
177                appRestrictions.put(Pair.create(pkg, user), bundle);
178
179                return null;
180            }
181        }).when(mContext.userManager).setApplicationRestrictions(
182                anyString(), any(Bundle.class), any(UserHandle.class));
183
184        // UM.getApplicationRestrictions() will read from appRestrictions.
185        doAnswer(new Answer<Bundle>() {
186            @Override
187            public Bundle answer(InvocationOnMock invocation) throws Throwable {
188                String pkg = (String) invocation.getArguments()[0];
189                UserHandle user = (UserHandle) invocation.getArguments()[1];
190
191                return appRestrictions.get(Pair.create(pkg, user));
192            }
193        }).when(mContext.userManager).getApplicationRestrictions(
194                anyString(), any(UserHandle.class));
195
196        // Add the first secondary user.
197        mContext.addUser(DpmMockContext.CALLER_USER_HANDLE, 0);
198    }
199
200    private void setAsProfileOwner(ComponentName admin) {
201        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
202        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
203
204        // PO needs to be an DA.
205        dpm.setActiveAdmin(admin, /* replace =*/ false);
206
207        // Fire!
208        assertTrue(dpm.setProfileOwner(admin, "owner-name", DpmMockContext.CALLER_USER_HANDLE));
209
210        // Check
211        assertEquals(admin, dpm.getProfileOwnerAsUser(DpmMockContext.CALLER_USER_HANDLE));
212    }
213
214    public void testHasNoFeature() throws Exception {
215        when(mContext.packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN)))
216                .thenReturn(false);
217
218        LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
219        new DevicePolicyManagerServiceTestable(mContext, dataDir);
220
221        // If the device has no DPMS feature, it shouldn't register the local service.
222        assertNull(LocalServices.getService(DevicePolicyManagerInternal.class));
223    }
224
225    /**
226     * Caller doesn't have proper permissions.
227     */
228    public void testSetActiveAdmin_SecurityException() {
229        // 1. Failure cases.
230
231        // Caller doesn't have MANAGE_DEVICE_ADMINS.
232        try {
233            dpm.setActiveAdmin(admin1, false);
234            fail("Didn't throw SecurityException");
235        } catch (SecurityException expected) {
236        }
237
238        // Caller has MANAGE_DEVICE_ADMINS, but for different user.
239        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
240        try {
241            dpm.setActiveAdmin(admin1, false, DpmMockContext.CALLER_USER_HANDLE + 1);
242            fail("Didn't throw SecurityException");
243        } catch (SecurityException expected) {
244        }
245    }
246
247    /**
248     * Test for:
249     * {@link DevicePolicyManager#setActiveAdmin}
250     * with replace=false and replace=true
251     * {@link DevicePolicyManager#isAdminActive}
252     * {@link DevicePolicyManager#isAdminActiveAsUser}
253     * {@link DevicePolicyManager#getActiveAdmins}
254     * {@link DevicePolicyManager#getActiveAdminsAsUser}
255     */
256    public void testSetActiveAdmin() throws Exception {
257        // 1. Make sure the caller has proper permissions.
258        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
259
260        // 2. Call the API.
261        dpm.setActiveAdmin(admin1, /* replace =*/ false);
262
263        // 3. Verify internal calls.
264
265        // Check if the boradcast is sent.
266        verify(mContext.spiedContext).sendBroadcastAsUser(
267                MockUtils.checkIntentAction(
268                        DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
269                MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE));
270        verify(mContext.spiedContext).sendBroadcastAsUser(
271                MockUtils.checkIntentAction(
272                        DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED),
273                MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE));
274
275        verify(mContext.ipackageManager, times(1)).setApplicationEnabledSetting(
276                eq(admin1.getPackageName()),
277                eq(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT),
278                eq(PackageManager.DONT_KILL_APP),
279                eq(DpmMockContext.CALLER_USER_HANDLE),
280                anyString());
281
282        // TODO Verify other calls too.
283
284        // Make sure it's active admin1.
285        assertTrue(dpm.isAdminActive(admin1));
286        assertFalse(dpm.isAdminActive(admin2));
287        assertFalse(dpm.isAdminActive(admin3));
288
289        // But not admin1 for a different user.
290
291        // For this to work, caller needs android.permission.INTERACT_ACROSS_USERS_FULL.
292        // (Because we're checking a different user's status from CALLER_USER_HANDLE.)
293        mContext.callerPermissions.add("android.permission.INTERACT_ACROSS_USERS_FULL");
294
295        assertFalse(dpm.isAdminActiveAsUser(admin1, DpmMockContext.CALLER_USER_HANDLE + 1));
296        assertFalse(dpm.isAdminActiveAsUser(admin2, DpmMockContext.CALLER_USER_HANDLE + 1));
297
298        mContext.callerPermissions.remove("android.permission.INTERACT_ACROSS_USERS_FULL");
299
300        // Next, add one more admin.
301        // Before doing so, update the application info, now it's enabled.
302        setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID,
303                PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
304
305        dpm.setActiveAdmin(admin2, /* replace =*/ false);
306
307        // Now we have two admins.
308        assertTrue(dpm.isAdminActive(admin1));
309        assertTrue(dpm.isAdminActive(admin2));
310        assertFalse(dpm.isAdminActive(admin3));
311
312        // Admin2 was already enabled, so setApplicationEnabledSetting() shouldn't have called
313        // again.  (times(1) because it was previously called for admin1)
314        verify(mContext.ipackageManager, times(1)).setApplicationEnabledSetting(
315                eq(admin1.getPackageName()),
316                eq(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT),
317                eq(PackageManager.DONT_KILL_APP),
318                eq(DpmMockContext.CALLER_USER_HANDLE),
319                anyString());
320
321        // 4. Add the same admin1 again without replace, which should throw.
322        try {
323            dpm.setActiveAdmin(admin1, /* replace =*/ false);
324            fail("Didn't throw");
325        } catch (IllegalArgumentException expected) {
326        }
327
328        // 5. Add the same admin1 again with replace, which should succeed.
329        dpm.setActiveAdmin(admin1, /* replace =*/ true);
330
331        // TODO make sure it's replaced.
332
333        // 6. Test getActiveAdmins()
334        List<ComponentName> admins = dpm.getActiveAdmins();
335        assertEquals(2, admins.size());
336        assertEquals(admin1, admins.get(0));
337        assertEquals(admin2, admins.get(1));
338
339        // Another user has no admins.
340        mContext.callerPermissions.add("android.permission.INTERACT_ACROSS_USERS_FULL");
341
342        assertEquals(0, DpmTestUtils.getListSizeAllowingNull(
343                dpm.getActiveAdminsAsUser(DpmMockContext.CALLER_USER_HANDLE + 1)));
344
345        mContext.callerPermissions.remove("android.permission.INTERACT_ACROSS_USERS_FULL");
346    }
347
348    public void testSetActiveAdmin_multiUsers() throws Exception {
349
350        final int ANOTHER_USER_ID = 100;
351        final int ANOTHER_ADMIN_UID = UserHandle.getUid(ANOTHER_USER_ID, 20456);
352
353        mMockContext.addUser(ANOTHER_USER_ID, 0); // Add one more user.
354
355        // Set up pacakge manager for the other user.
356        setUpPackageManagerForAdmin(admin2, ANOTHER_ADMIN_UID);
357
358        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
359
360        dpm.setActiveAdmin(admin1, /* replace =*/ false);
361
362        mMockContext.binder.callingUid = ANOTHER_ADMIN_UID;
363        dpm.setActiveAdmin(admin2, /* replace =*/ false);
364
365
366        mMockContext.binder.callingUid = DpmMockContext.CALLER_UID;
367        assertTrue(dpm.isAdminActive(admin1));
368        assertFalse(dpm.isAdminActive(admin2));
369
370        mMockContext.binder.callingUid = ANOTHER_ADMIN_UID;
371        assertFalse(dpm.isAdminActive(admin1));
372        assertTrue(dpm.isAdminActive(admin2));
373    }
374
375    /**
376     * Test for:
377     * {@link DevicePolicyManager#setActiveAdmin}
378     * with replace=false
379     */
380    public void testSetActiveAdmin_twiceWithoutReplace() throws Exception {
381        // 1. Make sure the caller has proper permissions.
382        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
383
384        dpm.setActiveAdmin(admin1, /* replace =*/ false);
385        assertTrue(dpm.isAdminActive(admin1));
386
387        // Add the same admin1 again without replace, which should throw.
388        try {
389            dpm.setActiveAdmin(admin1, /* replace =*/ false);
390            fail("Didn't throw");
391        } catch (IllegalArgumentException expected) {
392        }
393    }
394
395    /**
396     * Test for:
397     * {@link DevicePolicyManager#setActiveAdmin} when the admin isn't protected with
398     * BIND_DEVICE_ADMIN.
399     */
400    public void testSetActiveAdmin_permissionCheck() throws Exception {
401        // 1. Make sure the caller has proper permissions.
402        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
403
404        try {
405            dpm.setActiveAdmin(adminNoPerm, /* replace =*/ false);
406            fail();
407        } catch (IllegalArgumentException expected) {
408            assertTrue(expected.getMessage().contains(permission.BIND_DEVICE_ADMIN));
409        }
410        assertFalse(dpm.isAdminActive(adminNoPerm));
411
412        // Change the target API level to MNC.  Now it can be set as DA.
413        setUpPackageManagerForAdmin(adminNoPerm, DpmMockContext.CALLER_UID, null,
414                VERSION_CODES.M);
415        dpm.setActiveAdmin(adminNoPerm, /* replace =*/ false);
416        assertTrue(dpm.isAdminActive(adminNoPerm));
417
418        // TODO Test the "load from the file" case where DA will still be loaded even without
419        // BIND_DEVICE_ADMIN and target API is N.
420    }
421
422    /**
423     * Test for:
424     * {@link DevicePolicyManager#removeActiveAdmin}
425     */
426    public void testRemoveActiveAdmin_SecurityException() {
427        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
428
429        // Add admin.
430
431        dpm.setActiveAdmin(admin1, /* replace =*/ false);
432
433        assertTrue(dpm.isAdminActive(admin1));
434
435        assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
436
437        // Directly call the DPMS method with a different userid, which should fail.
438        try {
439            dpms.removeActiveAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE + 1);
440            fail("Didn't throw SecurityException");
441        } catch (SecurityException expected) {
442        }
443
444        // Try to remove active admin with a different caller userid should fail too, without
445        // having MANAGE_DEVICE_ADMINS.
446        mContext.callerPermissions.clear();
447
448        // Change the caller, and call into DPMS directly with a different user-id.
449
450        mContext.binder.callingUid = 1234567;
451        try {
452            dpms.removeActiveAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE);
453            fail("Didn't throw SecurityException");
454        } catch (SecurityException expected) {
455        }
456    }
457
458    /**
459     * {@link DevicePolicyManager#removeActiveAdmin} should fail with the user is not unlocked
460     * (because we can't send the remove broadcast).
461     */
462    public void testRemoveActiveAdmin_userNotRunningOrLocked() {
463        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
464
465        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
466
467        // Add admin.
468
469        dpm.setActiveAdmin(admin1, /* replace =*/ false);
470
471        assertTrue(dpm.isAdminActive(admin1));
472
473        assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
474
475        // 1. User not unlocked.
476        when(mContext.userManager.isUserUnlocked(eq(DpmMockContext.CALLER_USER_HANDLE)))
477                .thenReturn(false);
478        try {
479            dpm.removeActiveAdmin(admin1);
480            fail("Didn't throw IllegalStateException");
481        } catch (IllegalStateException expected) {
482            MoreAsserts.assertContainsRegex(
483                    "User must be running and unlocked", expected.getMessage());
484        }
485
486        assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
487
488        // 2. User unlocked.
489        when(mContext.userManager.isUserUnlocked(eq(DpmMockContext.CALLER_USER_HANDLE)))
490                .thenReturn(true);
491
492        dpm.removeActiveAdmin(admin1);
493        assertFalse(dpm.isAdminActiveAsUser(admin1, DpmMockContext.CALLER_USER_HANDLE));
494    }
495
496    /**
497     * Test for:
498     * {@link DevicePolicyManager#removeActiveAdmin}
499     */
500    public void testRemoveActiveAdmin_fromDifferentUserWithINTERACT_ACROSS_USERS_FULL() {
501        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
502
503        // Add admin1.
504
505        dpm.setActiveAdmin(admin1, /* replace =*/ false);
506
507        assertTrue(dpm.isAdminActive(admin1));
508        assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
509
510        // Different user, but should work, because caller has proper permissions.
511        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
512
513        // Change the caller, and call into DPMS directly with a different user-id.
514        mContext.binder.callingUid = 1234567;
515
516        dpms.removeActiveAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE);
517        assertFalse(dpm.isAdminActiveAsUser(admin1, DpmMockContext.CALLER_USER_HANDLE));
518
519        // TODO DO Still can't be removed in this case.
520    }
521
522    /**
523     * Test for:
524     * {@link DevicePolicyManager#removeActiveAdmin}
525     */
526    public void testRemoveActiveAdmin_sameUserNoMANAGE_DEVICE_ADMINS() {
527        // Need MANAGE_DEVICE_ADMINS for setActiveAdmin.  We'll remove it later.
528        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
529
530        // Add admin1.
531
532        dpm.setActiveAdmin(admin1, /* replace =*/ false);
533
534        assertTrue(dpm.isAdminActive(admin1));
535        assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
536
537        // Broadcast from saveSettingsLocked().
538        verify(mContext.spiedContext, times(1)).sendBroadcastAsUser(
539                MockUtils.checkIntentAction(
540                        DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
541                MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE));
542
543        // Remove.  No permissions, but same user, so it'll work.
544        mContext.callerPermissions.clear();
545        dpm.removeActiveAdmin(admin1);
546
547        verify(mContext.spiedContext).sendOrderedBroadcastAsUser(
548                MockUtils.checkIntentAction(
549                        DeviceAdminReceiver.ACTION_DEVICE_ADMIN_DISABLED),
550                MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE),
551                isNull(String.class),
552                any(BroadcastReceiver.class),
553                eq(dpms.mHandler),
554                eq(Activity.RESULT_OK),
555                isNull(String.class),
556                isNull(Bundle.class));
557
558        assertFalse(dpm.isAdminActiveAsUser(admin1, DpmMockContext.CALLER_USER_HANDLE));
559
560        // Again broadcast from saveSettingsLocked().
561        verify(mContext.spiedContext, times(2)).sendBroadcastAsUser(
562                MockUtils.checkIntentAction(
563                        DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
564                MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE));
565
566        // TODO Check other internal calls.
567    }
568
569    /**
570     * Test for: @{link DevicePolicyManager#setActivePasswordState}
571     *
572     * Validates that when the password for a user changes, the notification broadcast intent
573     * {@link DeviceAdminReceiver#ACTION_PASSWORD_CHANGED} is sent to managed profile owners, in
574     * addition to ones in the original user.
575     */
576    public void testSetActivePasswordState_sendToProfiles() throws Exception {
577        mContext.callerPermissions.add(permission.BIND_DEVICE_ADMIN);
578
579        final int MANAGED_PROFILE_USER_ID = 78;
580        final int MANAGED_PROFILE_ADMIN_UID =
581                UserHandle.getUid(MANAGED_PROFILE_USER_ID, DpmMockContext.SYSTEM_UID);
582
583        // Setup device owner.
584        mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
585        mContext.packageName = admin1.getPackageName();
586        setupDeviceOwner();
587
588        // Add a managed profile belonging to the system user.
589        addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
590
591        // Change the parent user's password.
592        dpm.reportPasswordChanged(UserHandle.USER_SYSTEM);
593
594        // Both the device owner and the managed profile owner should receive this broadcast.
595        final Intent intent = new Intent(DeviceAdminReceiver.ACTION_PASSWORD_CHANGED);
596        intent.setComponent(admin1);
597        intent.putExtra(Intent.EXTRA_USER, UserHandle.of(UserHandle.USER_SYSTEM));
598
599        verify(mContext.spiedContext, times(1)).sendBroadcastAsUser(
600                MockUtils.checkIntent(intent),
601                MockUtils.checkUserHandle(UserHandle.USER_SYSTEM));
602        verify(mContext.spiedContext, times(1)).sendBroadcastAsUser(
603                MockUtils.checkIntent(intent),
604                MockUtils.checkUserHandle(MANAGED_PROFILE_USER_ID));
605    }
606
607    /**
608     * Test for: @{link DevicePolicyManager#setActivePasswordState}
609     *
610     * Validates that when the password for a managed profile changes, the notification broadcast
611     * intent {@link DeviceAdminReceiver#ACTION_PASSWORD_CHANGED} is only sent to the profile, not
612     * its parent.
613     */
614    public void testSetActivePasswordState_notSentToParent() throws Exception {
615        mContext.callerPermissions.add(permission.BIND_DEVICE_ADMIN);
616
617        final int MANAGED_PROFILE_USER_ID = 78;
618        final int MANAGED_PROFILE_ADMIN_UID =
619                UserHandle.getUid(MANAGED_PROFILE_USER_ID, DpmMockContext.SYSTEM_UID);
620
621        // Setup device owner.
622        mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
623        mContext.packageName = admin1.getPackageName();
624        doReturn(true).when(mContext.lockPatternUtils)
625                .isSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID);
626        setupDeviceOwner();
627
628        // Add a managed profile belonging to the system user.
629        addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
630
631        // Change the profile's password.
632        dpm.reportPasswordChanged(MANAGED_PROFILE_USER_ID);
633
634        // Both the device owner and the managed profile owner should receive this broadcast.
635        final Intent intent = new Intent(DeviceAdminReceiver.ACTION_PASSWORD_CHANGED);
636        intent.setComponent(admin1);
637        intent.putExtra(Intent.EXTRA_USER, UserHandle.of(MANAGED_PROFILE_USER_ID));
638
639        verify(mContext.spiedContext, never()).sendBroadcastAsUser(
640                MockUtils.checkIntent(intent),
641                MockUtils.checkUserHandle(UserHandle.USER_SYSTEM));
642        verify(mContext.spiedContext, times(1)).sendBroadcastAsUser(
643                MockUtils.checkIntent(intent),
644                MockUtils.checkUserHandle(MANAGED_PROFILE_USER_ID));
645    }
646    /**
647     * Test for: {@link DevicePolicyManager#setDeviceOwner} DO on system user installs successfully.
648     */
649    public void testSetDeviceOwner() throws Exception {
650        setDeviceOwner();
651
652        // Try to set a profile owner on the same user, which should fail.
653        setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_SYSTEM_USER_UID);
654        dpm.setActiveAdmin(admin2, /* refreshing= */ true, UserHandle.USER_SYSTEM);
655        try {
656            dpm.setProfileOwner(admin2, "owner-name", UserHandle.USER_SYSTEM);
657            fail("IllegalStateException not thrown");
658        } catch (IllegalStateException expected) {
659            assertTrue("Message was: " + expected.getMessage(),
660                    expected.getMessage().contains("already has a device owner"));
661        }
662
663        // DO admin can't be deactivated.
664        dpm.removeActiveAdmin(admin1);
665        assertTrue(dpm.isAdminActive(admin1));
666
667        // TODO Test getDeviceOwnerName() too. To do so, we need to change
668        // DPMS.getApplicationLabel() because Context.createPackageContextAsUser() is not mockable.
669    }
670
671    private void setDeviceOwner() throws Exception {
672        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
673        mContext.callerPermissions.add(permission.MANAGE_USERS);
674        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
675        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
676
677        // In this test, change the caller user to "system".
678        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
679
680        // Make sure admin1 is installed on system user.
681        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
682
683        // Check various get APIs.
684        checkGetDeviceOwnerInfoApi(dpm, /* hasDeviceOwner =*/ false);
685
686        // DO needs to be an DA.
687        dpm.setActiveAdmin(admin1, /* replace =*/ false);
688
689        // Fire!
690        assertTrue(dpm.setDeviceOwner(admin1, "owner-name"));
691
692        // getDeviceOwnerComponent should return the admin1 component.
693        assertEquals(admin1, dpm.getDeviceOwnerComponentOnCallingUser());
694        assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
695
696        // Check various get APIs.
697        checkGetDeviceOwnerInfoApi(dpm, /* hasDeviceOwner =*/ true);
698
699        // getDeviceOwnerComponent should *NOT* return the admin1 component for other users.
700        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
701        assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser());
702        assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
703
704        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
705
706        // Verify internal calls.
707        verify(mContext.iactivityManager, times(1)).updateDeviceOwner(
708                eq(admin1.getPackageName()));
709
710        // TODO We should check if the caller has called clearCallerIdentity().
711        verify(mContext.ibackupManager, times(1)).setBackupServiceActive(
712                eq(UserHandle.USER_SYSTEM), eq(false));
713
714        verify(mContext.spiedContext, times(1)).sendBroadcastAsUser(
715                MockUtils.checkIntentAction(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED),
716                MockUtils.checkUserHandle(UserHandle.USER_SYSTEM));
717
718        assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
719    }
720
721    private void checkGetDeviceOwnerInfoApi(DevicePolicyManager dpm, boolean hasDeviceOwner) {
722        final int origCallingUser = mContext.binder.callingUid;
723        final List origPermissions = new ArrayList(mContext.callerPermissions);
724        mContext.callerPermissions.clear();
725
726        mContext.callerPermissions.add(permission.MANAGE_USERS);
727
728        mContext.binder.callingUid = Process.SYSTEM_UID;
729
730        // TODO Test getDeviceOwnerName() too.  To do so, we need to change
731        // DPMS.getApplicationLabel() because Context.createPackageContextAsUser() is not mockable.
732        if (hasDeviceOwner) {
733            assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName()));
734            assertTrue(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
735            assertEquals(admin1, dpm.getDeviceOwnerComponentOnCallingUser());
736
737            assertTrue(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
738            assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
739            assertEquals(UserHandle.USER_SYSTEM, dpm.getDeviceOwnerUserId());
740        } else {
741            assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName()));
742            assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
743            assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser());
744
745            assertFalse(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
746            assertEquals(null, dpm.getDeviceOwnerComponentOnAnyUser());
747            assertEquals(UserHandle.USER_NULL, dpm.getDeviceOwnerUserId());
748        }
749
750        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
751        if (hasDeviceOwner) {
752            assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName()));
753            assertTrue(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
754            assertEquals(admin1, dpm.getDeviceOwnerComponentOnCallingUser());
755
756            assertTrue(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
757            assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
758            assertEquals(UserHandle.USER_SYSTEM, dpm.getDeviceOwnerUserId());
759        } else {
760            assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName()));
761            assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
762            assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser());
763
764            assertFalse(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
765            assertEquals(null, dpm.getDeviceOwnerComponentOnAnyUser());
766            assertEquals(UserHandle.USER_NULL, dpm.getDeviceOwnerUserId());
767        }
768
769        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
770        // Still with MANAGE_USERS.
771        assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName()));
772        assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
773        assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser());
774
775        if (hasDeviceOwner) {
776            assertTrue(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
777            assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
778            assertEquals(UserHandle.USER_SYSTEM, dpm.getDeviceOwnerUserId());
779        } else {
780            assertFalse(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
781            assertEquals(null, dpm.getDeviceOwnerComponentOnAnyUser());
782            assertEquals(UserHandle.USER_NULL, dpm.getDeviceOwnerUserId());
783        }
784
785        mContext.binder.callingUid = Process.SYSTEM_UID;
786        mContext.callerPermissions.remove(permission.MANAGE_USERS);
787        // System can still call "OnAnyUser" without MANAGE_USERS.
788        if (hasDeviceOwner) {
789            assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName()));
790            assertTrue(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
791            assertEquals(admin1, dpm.getDeviceOwnerComponentOnCallingUser());
792
793            assertTrue(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
794            assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
795            assertEquals(UserHandle.USER_SYSTEM, dpm.getDeviceOwnerUserId());
796        } else {
797            assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName()));
798            assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
799            assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser());
800
801            assertFalse(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
802            assertEquals(null, dpm.getDeviceOwnerComponentOnAnyUser());
803            assertEquals(UserHandle.USER_NULL, dpm.getDeviceOwnerUserId());
804        }
805
806        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
807        // Still no MANAGE_USERS.
808        if (hasDeviceOwner) {
809            assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName()));
810            assertTrue(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
811            assertEquals(admin1, dpm.getDeviceOwnerComponentOnCallingUser());
812        } else {
813            assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName()));
814            assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
815            assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser());
816        }
817
818        try {
819            dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName());
820            fail();
821        } catch (SecurityException expected) {
822        }
823        try {
824            dpm.getDeviceOwnerComponentOnAnyUser();
825            fail();
826        } catch (SecurityException expected) {
827        }
828        try {
829            dpm.getDeviceOwnerUserId();
830            fail();
831        } catch (SecurityException expected) {
832        }
833        try {
834            dpm.getDeviceOwnerNameOnAnyUser();
835            fail();
836        } catch (SecurityException expected) {
837        }
838
839        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
840        // Still no MANAGE_USERS.
841        assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName()));
842        assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
843        assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser());
844
845        try {
846            dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName());
847            fail();
848        } catch (SecurityException expected) {
849        }
850        try {
851            dpm.getDeviceOwnerComponentOnAnyUser();
852            fail();
853        } catch (SecurityException expected) {
854        }
855        try {
856            dpm.getDeviceOwnerUserId();
857            fail();
858        } catch (SecurityException expected) {
859        }
860        try {
861            dpm.getDeviceOwnerNameOnAnyUser();
862            fail();
863        } catch (SecurityException expected) {
864        }
865
866        // Restore.
867        mContext.binder.callingUid = origCallingUser;
868        mContext.callerPermissions.addAll(origPermissions);
869    }
870
871
872    /**
873     * Test for: {@link DevicePolicyManager#setDeviceOwner} Package doesn't exist.
874     */
875    public void testSetDeviceOwner_noSuchPackage() {
876        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
877        mContext.callerPermissions.add(permission.MANAGE_USERS);
878        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
879        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
880
881        // Call from a process on the system user.
882        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
883
884        try {
885            dpm.setDeviceOwner(new ComponentName("a.b.c", ".def"));
886            fail("Didn't throw IllegalArgumentException");
887        } catch (IllegalArgumentException expected) {
888            assertTrue("Message was: " + expected.getMessage(),
889                    expected.getMessage().contains("Invalid component"));
890        }
891    }
892
893    public void testSetDeviceOwner_failures() throws Exception {
894        // TODO Test more failure cases.  Basically test all chacks in enforceCanSetDeviceOwner().
895    }
896
897    public void testClearDeviceOwner() throws Exception {
898        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
899        mContext.callerPermissions.add(permission.MANAGE_USERS);
900        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
901        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
902
903        // Set admin1 as a DA to the secondary user.
904        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID);
905
906        dpm.setActiveAdmin(admin1, /* replace =*/ false);
907
908        // Set admin 1 as the DO to the system user.
909
910        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
911        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
912        dpm.setActiveAdmin(admin1, /* replace =*/ false);
913        assertTrue(dpm.setDeviceOwner(admin1, "owner-name"));
914
915        // Verify internal calls.
916        verify(mContext.iactivityManager, times(1)).updateDeviceOwner(
917                eq(admin1.getPackageName()));
918
919        assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
920
921        dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADD_USER);
922        when(mContext.userManager.hasUserRestriction(eq(UserManager.DISALLOW_ADD_USER),
923                MockUtils.checkUserHandle(UserHandle.USER_SYSTEM))).thenReturn(true);
924
925        assertTrue(dpm.isAdminActive(admin1));
926        assertFalse(dpm.isRemovingAdmin(admin1, UserHandle.USER_SYSTEM));
927
928        // Set up other mocks.
929        when(mContext.userManager.getUserRestrictions()).thenReturn(new Bundle());
930
931        // Now call clear.
932        doReturn(DpmMockContext.CALLER_SYSTEM_USER_UID).when(mContext.packageManager).getPackageUidAsUser(
933                eq(admin1.getPackageName()),
934                anyInt());
935
936        // But first pretend the user is locked.  Then it should fail.
937        when(mContext.userManager.isUserUnlocked(anyInt())).thenReturn(false);
938        try {
939            dpm.clearDeviceOwnerApp(admin1.getPackageName());
940            fail("Didn't throw IllegalStateException");
941        } catch (IllegalStateException expected) {
942            MoreAsserts.assertContainsRegex(
943                    "User must be running and unlocked", expected.getMessage());
944        }
945
946        when(mContext.userManager.isUserUnlocked(anyInt())).thenReturn(true);
947        reset(mContext.userManagerInternal);
948        dpm.clearDeviceOwnerApp(admin1.getPackageName());
949
950        // Now DO shouldn't be set.
951        assertNull(dpm.getDeviceOwnerComponentOnAnyUser());
952
953        verify(mContext.userManager).setUserRestriction(eq(UserManager.DISALLOW_ADD_USER),
954                eq(false),
955                MockUtils.checkUserHandle(UserHandle.USER_SYSTEM));
956
957        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
958                eq(UserHandle.USER_SYSTEM),
959                eq(null),
960                eq(true), eq(CAMERA_NOT_DISABLED));
961
962        assertFalse(dpm.isAdminActiveAsUser(admin1, UserHandle.USER_SYSTEM));
963
964        // ACTION_DEVICE_OWNER_CHANGED should be sent twice, once for setting the device owner
965        // and once for clearing it.
966        verify(mContext.spiedContext, times(2)).sendBroadcastAsUser(
967                MockUtils.checkIntentAction(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED),
968                MockUtils.checkUserHandle(UserHandle.USER_SYSTEM));
969        // TODO Check other calls.
970    }
971
972    public void testClearDeviceOwner_fromDifferentUser() throws Exception {
973        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
974        mContext.callerPermissions.add(permission.MANAGE_USERS);
975        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
976        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
977
978        // Set admin1 as a DA to the secondary user.
979        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID);
980
981        dpm.setActiveAdmin(admin1, /* replace =*/ false);
982
983        // Set admin 1 as the DO to the system user.
984
985        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
986        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
987        dpm.setActiveAdmin(admin1, /* replace =*/ false);
988        assertTrue(dpm.setDeviceOwner(admin1, "owner-name"));
989
990        // Verify internal calls.
991        verify(mContext.iactivityManager, times(1)).updateDeviceOwner(
992                eq(admin1.getPackageName()));
993
994        assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
995
996        // Now call clear from the secondary user, which should throw.
997        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
998
999        // Now call clear.
1000        doReturn(DpmMockContext.CALLER_UID).when(mContext.packageManager).getPackageUidAsUser(
1001                eq(admin1.getPackageName()),
1002                anyInt());
1003        try {
1004            dpm.clearDeviceOwnerApp(admin1.getPackageName());
1005            fail("Didn't throw");
1006        } catch (SecurityException e) {
1007            assertEquals("clearDeviceOwner can only be called by the device owner", e.getMessage());
1008        }
1009
1010        // DO shouldn't be removed.
1011        assertTrue(dpm.isDeviceManaged());
1012    }
1013
1014    public void testSetProfileOwner() throws Exception {
1015        setAsProfileOwner(admin1);
1016
1017        // PO admin can't be deactivated.
1018        dpm.removeActiveAdmin(admin1);
1019        assertTrue(dpm.isAdminActive(admin1));
1020
1021        // Try setting DO on the same user, which should fail.
1022        setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID);
1023        dpm.setActiveAdmin(admin2, /* refreshing= */ true, DpmMockContext.CALLER_USER_HANDLE);
1024        try {
1025            dpm.setDeviceOwner(admin2, "owner-name", DpmMockContext.CALLER_USER_HANDLE);
1026            fail("IllegalStateException not thrown");
1027        } catch (IllegalStateException expected) {
1028            assertTrue("Message was: " + expected.getMessage(),
1029                    expected.getMessage().contains("already has a profile owner"));
1030        }
1031    }
1032
1033    public void testClearProfileOwner() throws Exception {
1034        setAsProfileOwner(admin1);
1035
1036        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
1037
1038        assertTrue(dpm.isProfileOwnerApp(admin1.getPackageName()));
1039        assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
1040
1041        // First try when the user is locked, which should fail.
1042        when(mContext.userManager.isUserUnlocked(anyInt()))
1043                .thenReturn(false);
1044        try {
1045            dpm.clearProfileOwner(admin1);
1046            fail("Didn't throw IllegalStateException");
1047        } catch (IllegalStateException expected) {
1048            MoreAsserts.assertContainsRegex(
1049                    "User must be running and unlocked", expected.getMessage());
1050        }
1051        // Clear, really.
1052        when(mContext.userManager.isUserUnlocked(anyInt()))
1053                .thenReturn(true);
1054        dpm.clearProfileOwner(admin1);
1055
1056        // Check
1057        assertFalse(dpm.isProfileOwnerApp(admin1.getPackageName()));
1058        assertFalse(dpm.isAdminActiveAsUser(admin1, DpmMockContext.CALLER_USER_HANDLE));
1059    }
1060
1061    public void testSetProfileOwner_failures() throws Exception {
1062        // TODO Test more failure cases.  Basically test all chacks in enforceCanSetProfileOwner().
1063    }
1064
1065    public void testGetDeviceOwnerAdminLocked() throws Exception {
1066        checkDeviceOwnerWithMultipleDeviceAdmins();
1067    }
1068
1069    private void checkDeviceOwnerWithMultipleDeviceAdmins() throws Exception {
1070        // In ths test, we use 3 users (system + 2 secondary users), set some device admins to them,
1071        // set admin2 on CALLER_USER_HANDLE as DO, then call getDeviceOwnerAdminLocked() to
1072        // make sure it gets the right component from the right user.
1073
1074        final int ANOTHER_USER_ID = 100;
1075        final int ANOTHER_ADMIN_UID = UserHandle.getUid(ANOTHER_USER_ID, 456);
1076
1077        mMockContext.addUser(ANOTHER_USER_ID, 0); // Add one more user.
1078
1079        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
1080        mContext.callerPermissions.add(permission.MANAGE_USERS);
1081        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
1082        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
1083
1084        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
1085
1086        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
1087
1088        // Make sure the admin packge is installed to each user.
1089        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
1090        setUpPackageManagerForAdmin(admin3, DpmMockContext.CALLER_SYSTEM_USER_UID);
1091
1092        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID);
1093        setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID);
1094
1095        setUpPackageManagerForAdmin(admin2, ANOTHER_ADMIN_UID);
1096
1097
1098        // Set active admins to the users.
1099        dpm.setActiveAdmin(admin1, /* replace =*/ false);
1100        dpm.setActiveAdmin(admin3, /* replace =*/ false);
1101
1102        dpm.setActiveAdmin(admin1, /* replace =*/ false, DpmMockContext.CALLER_USER_HANDLE);
1103        dpm.setActiveAdmin(admin2, /* replace =*/ false, DpmMockContext.CALLER_USER_HANDLE);
1104
1105        dpm.setActiveAdmin(admin2, /* replace =*/ false, ANOTHER_USER_ID);
1106
1107        // Set DO on the first non-system user.
1108        mContext.setUserRunning(DpmMockContext.CALLER_USER_HANDLE, true);
1109        assertTrue(dpm.setDeviceOwner(admin2, "owner-name", DpmMockContext.CALLER_USER_HANDLE));
1110
1111        assertEquals(admin2, dpms.getDeviceOwnerComponent(/* callingUserOnly =*/ false));
1112
1113        // Then check getDeviceOwnerAdminLocked().
1114        assertEquals(admin2, dpms.getDeviceOwnerAdminLocked().info.getComponent());
1115        assertEquals(DpmMockContext.CALLER_UID, dpms.getDeviceOwnerAdminLocked().getUid());
1116    }
1117
1118    /**
1119     * This essentially tests
1120     * {@code DevicePolicyManagerService.findOwnerComponentIfNecessaryLocked()}. (which is
1121     * private.)
1122     *
1123     * We didn't use to persist the DO component class name, but now we do, and the above method
1124     * finds the right component from a package name upon migration.
1125     */
1126    public void testDeviceOwnerMigration() throws Exception {
1127        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
1128        checkDeviceOwnerWithMultipleDeviceAdmins();
1129
1130        // Overwrite the device owner setting and clears the clas name.
1131        dpms.mOwners.setDeviceOwner(
1132                new ComponentName(admin2.getPackageName(), ""),
1133                "owner-name", DpmMockContext.CALLER_USER_HANDLE);
1134        dpms.mOwners.writeDeviceOwner();
1135
1136        // Make sure the DO component name doesn't have a class name.
1137        assertEquals("", dpms.getDeviceOwnerComponent(/* callingUserOnly =*/ false).getClassName());
1138
1139        // Then create a new DPMS to have it load the settings from files.
1140        when(mContext.userManager.getUserRestrictions(any(UserHandle.class)))
1141                .thenReturn(new Bundle());
1142        initializeDpms();
1143
1144        // Now the DO component name is a full name.
1145        // *BUT* because both admin1 and admin2 belong to the same package, we think admin1 is the
1146        // DO.
1147        assertEquals(admin1, dpms.getDeviceOwnerComponent(/* callingUserOnly =*/ false));
1148    }
1149
1150    public void testSetGetApplicationRestriction() {
1151        setAsProfileOwner(admin1);
1152        mContext.packageName = admin1.getPackageName();
1153
1154        {
1155            Bundle rest = new Bundle();
1156            rest.putString("KEY_STRING", "Foo1");
1157            dpm.setApplicationRestrictions(admin1, "pkg1", rest);
1158        }
1159
1160        {
1161            Bundle rest = new Bundle();
1162            rest.putString("KEY_STRING", "Foo2");
1163            dpm.setApplicationRestrictions(admin1, "pkg2", rest);
1164        }
1165
1166        {
1167            Bundle returned = dpm.getApplicationRestrictions(admin1, "pkg1");
1168            assertNotNull(returned);
1169            assertEquals(returned.size(), 1);
1170            assertEquals(returned.get("KEY_STRING"), "Foo1");
1171        }
1172
1173        {
1174            Bundle returned = dpm.getApplicationRestrictions(admin1, "pkg2");
1175            assertNotNull(returned);
1176            assertEquals(returned.size(), 1);
1177            assertEquals(returned.get("KEY_STRING"), "Foo2");
1178        }
1179
1180        dpm.setApplicationRestrictions(admin1, "pkg2", new Bundle());
1181        assertEquals(0, dpm.getApplicationRestrictions(admin1, "pkg2").size());
1182    }
1183
1184    /**
1185     * Setup a package in the package manager mock. Useful for faking installed applications.
1186     *
1187     * @param packageName the name of the package to be setup
1188     * @param appId the application ID to be given to the package
1189     * @return the UID of the package as known by the mock package manager
1190     */
1191    private int setupPackageInPackageManager(final String packageName, final int appId)
1192            throws Exception {
1193        // Make the PackageManager return the package instead of throwing a NameNotFoundException
1194        final PackageInfo pi = new PackageInfo();
1195        pi.applicationInfo = new ApplicationInfo();
1196        pi.applicationInfo.flags = ApplicationInfo.FLAG_HAS_CODE;
1197        doReturn(pi).when(mContext.ipackageManager).getPackageInfo(
1198                eq(packageName),
1199                anyInt(),
1200                eq(DpmMockContext.CALLER_USER_HANDLE));
1201        // Setup application UID with the PackageManager
1202        final int uid = UserHandle.getUid(DpmMockContext.CALLER_USER_HANDLE, appId);
1203        doReturn(uid).when(mContext.packageManager).getPackageUidAsUser(
1204                eq(packageName),
1205                eq(DpmMockContext.CALLER_USER_HANDLE));
1206        // Associate packageName to uid
1207        doReturn(packageName).when(mContext.ipackageManager).getNameForUid(eq(uid));
1208        doReturn(new String[]{packageName})
1209            .when(mContext.ipackageManager).getPackagesForUid(eq(uid));
1210        return uid;
1211    }
1212
1213    public void testCertificateDisclosure() throws Exception {
1214        final int userId = DpmMockContext.CALLER_USER_HANDLE;
1215        final UserHandle user = UserHandle.of(userId);
1216
1217        mContext.applicationInfo = new ApplicationInfo();
1218        mContext.callerPermissions.add(permission.MANAGE_USERS);
1219        mContext.packageName = "com.android.frameworks.servicestests";
1220        mContext.userContexts.put(user, mContext);
1221        when(mContext.resources.getColor(anyInt(), anyObject())).thenReturn(Color.WHITE);
1222
1223        ParceledListSlice<ParcelableString> oneCert = asSlice(new String[] {"1"});
1224        ParceledListSlice<ParcelableString> fourCerts = asSlice(new String[] {"1", "2", "3", "4"});
1225
1226        final String TEST_STRING = "Test for exactly 2 certs out of 4";
1227        doReturn(TEST_STRING).when(mContext.resources).getQuantityText(anyInt(), eq(2));
1228
1229        // Given that we have exactly one certificate installed,
1230        when(mContext.keyChainConnection.getService().getUserCaAliases()).thenReturn(oneCert);
1231        // when that certificate is approved,
1232        dpms.approveCaCert(oneCert.getList().get(0).string, userId, true);
1233        // a notification should not be shown.
1234        verify(mContext.notificationManager, timeout(1000))
1235                .cancelAsUser(anyString(), anyInt(), eq(user));
1236
1237        // Given that we have four certificates installed,
1238        when(mContext.keyChainConnection.getService().getUserCaAliases()).thenReturn(fourCerts);
1239        // when two of them are approved (one of them approved twice hence no action),
1240        dpms.approveCaCert(fourCerts.getList().get(0).string, userId, true);
1241        dpms.approveCaCert(fourCerts.getList().get(1).string, userId, true);
1242        // a notification should be shown saying that there are two certificates left to approve.
1243        verify(mContext.notificationManager, timeout(1000))
1244                .notifyAsUser(anyString(), anyInt(), argThat(
1245                        new BaseMatcher<Notification>() {
1246                            @Override
1247                            public boolean matches(Object item) {
1248                                final Notification noti = (Notification) item;
1249                                return TEST_STRING.equals(
1250                                        noti.extras.getString(Notification.EXTRA_TITLE));
1251                            }
1252                            @Override
1253                            public void describeTo(Description description) {
1254                                description.appendText(
1255                                        "Notification{title=\"" + TEST_STRING + "\"}");
1256                            }
1257                        }), eq(user));
1258    }
1259
1260    /**
1261     * Simple test for delegate set/get and general delegation. Tests verifying that delegated
1262     * privileges can acually be exercised by a delegate are not covered here.
1263     */
1264    public void testDelegation() throws Exception {
1265        setAsProfileOwner(admin1);
1266
1267        final int userHandle = DpmMockContext.CALLER_USER_HANDLE;
1268
1269        // Given two packages
1270        final String CERT_DELEGATE = "com.delegate.certs";
1271        final String RESTRICTIONS_DELEGATE = "com.delegate.apprestrictions";
1272        final int CERT_DELEGATE_UID = setupPackageInPackageManager(CERT_DELEGATE, 20988);
1273        final int RESTRICTIONS_DELEGATE_UID = setupPackageInPackageManager(RESTRICTIONS_DELEGATE,
1274                20989);
1275
1276        // On delegation
1277        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
1278        mContext.packageName = admin1.getPackageName();
1279        dpm.setCertInstallerPackage(admin1, CERT_DELEGATE);
1280        dpm.setApplicationRestrictionsManagingPackage(admin1, RESTRICTIONS_DELEGATE);
1281
1282        // DPMS correctly stores and retrieves the delegates
1283        DevicePolicyManagerService.DevicePolicyData policy = dpms.mUserData.get(userHandle);
1284        assertEquals(2, policy.mDelegationMap.size());
1285        MoreAsserts.assertContentsInAnyOrder(policy.mDelegationMap.get(CERT_DELEGATE),
1286            DELEGATION_CERT_INSTALL);
1287        MoreAsserts.assertContentsInAnyOrder(dpm.getDelegatedScopes(admin1, CERT_DELEGATE),
1288            DELEGATION_CERT_INSTALL);
1289        assertEquals(CERT_DELEGATE, dpm.getCertInstallerPackage(admin1));
1290        MoreAsserts.assertContentsInAnyOrder(policy.mDelegationMap.get(RESTRICTIONS_DELEGATE),
1291            DELEGATION_APP_RESTRICTIONS);
1292        MoreAsserts.assertContentsInAnyOrder(dpm.getDelegatedScopes(admin1, RESTRICTIONS_DELEGATE),
1293            DELEGATION_APP_RESTRICTIONS);
1294        assertEquals(RESTRICTIONS_DELEGATE, dpm.getApplicationRestrictionsManagingPackage(admin1));
1295
1296        // On calling install certificate APIs from an unauthorized process
1297        mContext.binder.callingUid = RESTRICTIONS_DELEGATE_UID;
1298        mContext.packageName = RESTRICTIONS_DELEGATE;
1299
1300        // DPMS throws a SecurityException
1301        try {
1302            dpm.installCaCert(null, null);
1303            fail("Didn't throw SecurityException on unauthorized access");
1304        } catch (SecurityException expected) {
1305        }
1306
1307        // On calling install certificate APIs from an authorized process
1308        mContext.binder.callingUid = CERT_DELEGATE_UID;
1309        mContext.packageName = CERT_DELEGATE;
1310
1311        // DPMS executes without a SecurityException
1312        try {
1313            dpm.installCaCert(null, null);
1314        } catch (SecurityException unexpected) {
1315            fail("Threw SecurityException on authorized access");
1316        } catch (NullPointerException expected) {
1317        }
1318
1319        // On removing a delegate
1320        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
1321        mContext.packageName = admin1.getPackageName();
1322        dpm.setCertInstallerPackage(admin1, null);
1323
1324        // DPMS does not allow access to ex-delegate
1325        mContext.binder.callingUid = CERT_DELEGATE_UID;
1326        mContext.packageName = CERT_DELEGATE;
1327        try {
1328            dpm.installCaCert(null, null);
1329            fail("Didn't throw SecurityException on unauthorized access");
1330        } catch (SecurityException expected) {
1331        }
1332
1333        // But still allows access to other existing delegates
1334        mContext.binder.callingUid = RESTRICTIONS_DELEGATE_UID;
1335        mContext.packageName = RESTRICTIONS_DELEGATE;
1336        try {
1337            dpm.getApplicationRestrictions(null, "pkg");
1338        } catch (SecurityException expected) {
1339            fail("Threw SecurityException on authorized access");
1340        }
1341    }
1342
1343    public void testApplicationRestrictionsManagingApp() throws Exception {
1344        setAsProfileOwner(admin1);
1345
1346        final String nonExistAppRestrictionsManagerPackage = "com.google.app.restrictions.manager2";
1347        final String appRestrictionsManagerPackage = "com.google.app.restrictions.manager";
1348        final int appRestrictionsManagerAppId = 20987;
1349        final int appRestrictionsManagerUid = setupPackageInPackageManager(
1350                appRestrictionsManagerPackage, appRestrictionsManagerAppId);
1351
1352        // appRestrictionsManager package shouldn't be able to manage restrictions as the PO hasn't
1353        // delegated that permission yet.
1354        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
1355        mContext.packageName = admin1.getPackageName();
1356        assertFalse(dpm.isCallerApplicationRestrictionsManagingPackage());
1357        Bundle rest = new Bundle();
1358        rest.putString("KEY_STRING", "Foo1");
1359        try {
1360            dpm.setApplicationRestrictions(null, "pkg1", rest);
1361            fail("Didn't throw expected SecurityException");
1362        } catch (SecurityException expected) {
1363            MoreAsserts.assertContainsRegex(
1364                    "Caller with uid \\d+ is not a delegate of scope delegation-app-restrictions.",
1365                    expected.getMessage());
1366        }
1367        try {
1368            dpm.getApplicationRestrictions(null, "pkg1");
1369            fail("Didn't throw expected SecurityException");
1370        } catch (SecurityException expected) {
1371            MoreAsserts.assertContainsRegex(
1372                    "Caller with uid \\d+ is not a delegate of scope delegation-app-restrictions.",
1373                    expected.getMessage());
1374        }
1375
1376        // Check via the profile owner that no restrictions were set.
1377        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
1378        mContext.packageName = admin1.getPackageName();
1379        assertEquals(0, dpm.getApplicationRestrictions(admin1, "pkg1").size());
1380
1381        // Check the API does not allow setting a non-existent package
1382        try {
1383            dpm.setApplicationRestrictionsManagingPackage(admin1,
1384                    nonExistAppRestrictionsManagerPackage);
1385            fail("Non-existent app set as app restriction manager.");
1386        } catch (PackageManager.NameNotFoundException expected) {
1387            MoreAsserts.assertContainsRegex(
1388                    nonExistAppRestrictionsManagerPackage, expected.getMessage());
1389        }
1390
1391        // Let appRestrictionsManagerPackage manage app restrictions
1392        dpm.setApplicationRestrictionsManagingPackage(admin1, appRestrictionsManagerPackage);
1393        assertEquals(appRestrictionsManagerPackage,
1394                dpm.getApplicationRestrictionsManagingPackage(admin1));
1395
1396        // Now that package should be able to set and retrieve app restrictions.
1397        mContext.binder.callingUid = appRestrictionsManagerUid;
1398        mContext.packageName = appRestrictionsManagerPackage;
1399        assertTrue(dpm.isCallerApplicationRestrictionsManagingPackage());
1400        dpm.setApplicationRestrictions(null, "pkg1", rest);
1401        Bundle returned = dpm.getApplicationRestrictions(null, "pkg1");
1402        assertEquals(1, returned.size(), 1);
1403        assertEquals("Foo1", returned.get("KEY_STRING"));
1404
1405        // The same app running on a separate user shouldn't be able to manage app restrictions.
1406        mContext.binder.callingUid = UserHandle.getUid(
1407                UserHandle.USER_SYSTEM, appRestrictionsManagerAppId);
1408        assertFalse(dpm.isCallerApplicationRestrictionsManagingPackage());
1409        try {
1410            dpm.setApplicationRestrictions(null, "pkg1", rest);
1411            fail("Didn't throw expected SecurityException");
1412        } catch (SecurityException expected) {
1413            MoreAsserts.assertContainsRegex(
1414                    "Caller with uid \\d+ is not a delegate of scope delegation-app-restrictions.",
1415                    expected.getMessage());
1416        }
1417
1418        // The DPM is still able to manage app restrictions, even if it allowed another app to do it
1419        // too.
1420        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
1421        mContext.packageName = admin1.getPackageName();
1422        assertEquals(returned, dpm.getApplicationRestrictions(admin1, "pkg1"));
1423        dpm.setApplicationRestrictions(admin1, "pkg1", null);
1424        assertEquals(0, dpm.getApplicationRestrictions(admin1, "pkg1").size());
1425
1426        // Removing the ability for the package to manage app restrictions.
1427        dpm.setApplicationRestrictionsManagingPackage(admin1, null);
1428        assertNull(dpm.getApplicationRestrictionsManagingPackage(admin1));
1429        mContext.binder.callingUid = appRestrictionsManagerUid;
1430        mContext.packageName = appRestrictionsManagerPackage;
1431        assertFalse(dpm.isCallerApplicationRestrictionsManagingPackage());
1432        try {
1433            dpm.setApplicationRestrictions(null, "pkg1", null);
1434            fail("Didn't throw expected SecurityException");
1435        } catch (SecurityException expected) {
1436            MoreAsserts.assertContainsRegex(
1437                    "Caller with uid \\d+ is not a delegate of scope delegation-app-restrictions.",
1438                    expected.getMessage());
1439        }
1440    }
1441
1442    public void testSetUserRestriction_asDo() throws Exception {
1443        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
1444        mContext.callerPermissions.add(permission.MANAGE_USERS);
1445        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
1446        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
1447
1448        // First, set DO.
1449
1450        // Call from a process on the system user.
1451        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
1452
1453        // Make sure admin1 is installed on system user.
1454        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
1455
1456        // Call.
1457        dpm.setActiveAdmin(admin1, /* replace =*/ false, UserHandle.USER_SYSTEM);
1458        assertTrue(dpm.setDeviceOwner(admin1, "owner-name",
1459                UserHandle.USER_SYSTEM));
1460
1461        // Check that the user restrictions that are enabled by default are set. Then unset them.
1462        String[] defaultRestrictions = UserRestrictionsUtils
1463                .getDefaultEnabledForDeviceOwner().toArray(new String[0]);
1464        DpmTestUtils.assertRestrictions(
1465                DpmTestUtils.newRestrictions(defaultRestrictions),
1466                dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions()
1467        );
1468        DpmTestUtils.assertRestrictions(
1469                DpmTestUtils.newRestrictions(defaultRestrictions),
1470                dpm.getUserRestrictions(admin1)
1471        );
1472        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1473                eq(UserHandle.USER_SYSTEM),
1474                MockUtils.checkUserRestrictions(defaultRestrictions),
1475                eq(true) /* isDeviceOwner */,
1476                eq(CAMERA_NOT_DISABLED)
1477        );
1478        reset(mContext.userManagerInternal);
1479
1480        for (String restriction : defaultRestrictions) {
1481            dpm.clearUserRestriction(admin1, restriction);
1482        }
1483
1484        assertNoDeviceOwnerRestrictions();
1485        reset(mContext.userManagerInternal);
1486
1487        dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADD_USER);
1488        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1489                eq(UserHandle.USER_SYSTEM),
1490                MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADD_USER),
1491                eq(true), eq(CAMERA_NOT_DISABLED));
1492        reset(mContext.userManagerInternal);
1493
1494        dpm.addUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS);
1495        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1496                eq(UserHandle.USER_SYSTEM),
1497                MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS,
1498                        UserManager.DISALLOW_ADD_USER),
1499                eq(true), eq(CAMERA_NOT_DISABLED));
1500        reset(mContext.userManagerInternal);
1501
1502        DpmTestUtils.assertRestrictions(
1503                DpmTestUtils.newRestrictions(
1504                        UserManager.DISALLOW_ADD_USER, UserManager.DISALLOW_OUTGOING_CALLS),
1505                dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions()
1506        );
1507        DpmTestUtils.assertRestrictions(
1508                DpmTestUtils.newRestrictions(
1509                        UserManager.DISALLOW_ADD_USER, UserManager.DISALLOW_OUTGOING_CALLS),
1510                dpm.getUserRestrictions(admin1)
1511        );
1512
1513        dpm.clearUserRestriction(admin1, UserManager.DISALLOW_ADD_USER);
1514        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1515                eq(UserHandle.USER_SYSTEM),
1516                MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS),
1517                eq(true), eq(CAMERA_NOT_DISABLED));
1518        reset(mContext.userManagerInternal);
1519
1520        DpmTestUtils.assertRestrictions(
1521                DpmTestUtils.newRestrictions(UserManager.DISALLOW_OUTGOING_CALLS),
1522                dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions()
1523        );
1524        DpmTestUtils.assertRestrictions(
1525                DpmTestUtils.newRestrictions(UserManager.DISALLOW_OUTGOING_CALLS),
1526                dpm.getUserRestrictions(admin1)
1527        );
1528
1529        dpm.clearUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS);
1530        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1531                eq(UserHandle.USER_SYSTEM),
1532                MockUtils.checkUserRestrictions(),
1533                eq(true), eq(CAMERA_NOT_DISABLED));
1534        reset(mContext.userManagerInternal);
1535
1536        assertNoDeviceOwnerRestrictions();
1537
1538        // DISALLOW_ADJUST_VOLUME and DISALLOW_UNMUTE_MICROPHONE are PO restrictions, but when
1539        // DO sets them, the scope is global.
1540        dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADJUST_VOLUME);
1541        reset(mContext.userManagerInternal);
1542        dpm.addUserRestriction(admin1, UserManager.DISALLOW_UNMUTE_MICROPHONE);
1543        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1544                eq(UserHandle.USER_SYSTEM),
1545                MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADJUST_VOLUME,
1546                        UserManager.DISALLOW_UNMUTE_MICROPHONE),
1547                eq(true), eq(CAMERA_NOT_DISABLED));
1548        reset(mContext.userManagerInternal);
1549
1550        dpm.clearUserRestriction(admin1, UserManager.DISALLOW_ADJUST_VOLUME);
1551        dpm.clearUserRestriction(admin1, UserManager.DISALLOW_UNMUTE_MICROPHONE);
1552        reset(mContext.userManagerInternal);
1553
1554        // More tests.
1555        dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADD_USER);
1556        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1557                eq(UserHandle.USER_SYSTEM),
1558                MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADD_USER),
1559                eq(true), eq(CAMERA_NOT_DISABLED));
1560        reset(mContext.userManagerInternal);
1561
1562        dpm.addUserRestriction(admin1, UserManager.DISALLOW_FUN);
1563        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1564                eq(UserHandle.USER_SYSTEM),
1565                MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN,
1566                        UserManager.DISALLOW_ADD_USER),
1567                eq(true), eq(CAMERA_NOT_DISABLED));
1568        reset(mContext.userManagerInternal);
1569
1570        dpm.setCameraDisabled(admin1, true);
1571        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1572                eq(UserHandle.USER_SYSTEM),
1573                // DISALLOW_CAMERA will be applied to both local and global.
1574                MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN,
1575                        UserManager.DISALLOW_ADD_USER),
1576                eq(true), eq(CAMERA_DISABLED_GLOBALLY));
1577        reset(mContext.userManagerInternal);
1578
1579        // Set up another DA and let it disable camera.  Now DISALLOW_CAMERA will only be applied
1580        // locally.
1581        dpm.setCameraDisabled(admin1, false);
1582        reset(mContext.userManagerInternal);
1583
1584        setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_SYSTEM_USER_UID);
1585        dpm.setActiveAdmin(admin2, /* replace =*/ false, UserHandle.USER_SYSTEM);
1586        dpm.setCameraDisabled(admin2, true);
1587
1588        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1589                eq(UserHandle.USER_SYSTEM),
1590                // DISALLOW_CAMERA will be applied to both local and global. <- TODO: fix this
1591                MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN,
1592                        UserManager.DISALLOW_ADD_USER),
1593                eq(true), eq(CAMERA_DISABLED_LOCALLY));
1594        reset(mContext.userManagerInternal);
1595        // TODO Make sure restrictions are written to the file.
1596    }
1597
1598    public void testSetUserRestriction_asPo() {
1599        setAsProfileOwner(admin1);
1600
1601        DpmTestUtils.assertRestrictions(
1602                DpmTestUtils.newRestrictions(),
1603                dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE)
1604                        .ensureUserRestrictions()
1605        );
1606
1607        dpm.addUserRestriction(admin1, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
1608        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1609                eq(DpmMockContext.CALLER_USER_HANDLE),
1610                MockUtils.checkUserRestrictions(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES),
1611                eq(false), eq(CAMERA_NOT_DISABLED));
1612        reset(mContext.userManagerInternal);
1613
1614        dpm.addUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS);
1615        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1616                eq(DpmMockContext.CALLER_USER_HANDLE),
1617                MockUtils.checkUserRestrictions(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
1618                        UserManager.DISALLOW_OUTGOING_CALLS),
1619                eq(false), eq(CAMERA_NOT_DISABLED));
1620        reset(mContext.userManagerInternal);
1621
1622        DpmTestUtils.assertRestrictions(
1623                DpmTestUtils.newRestrictions(
1624                        UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
1625                        UserManager.DISALLOW_OUTGOING_CALLS
1626                ),
1627                dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE)
1628                        .ensureUserRestrictions()
1629        );
1630        DpmTestUtils.assertRestrictions(
1631                DpmTestUtils.newRestrictions(
1632                        UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
1633                        UserManager.DISALLOW_OUTGOING_CALLS
1634                ),
1635                dpm.getUserRestrictions(admin1)
1636        );
1637
1638        dpm.clearUserRestriction(admin1, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
1639        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1640                eq(DpmMockContext.CALLER_USER_HANDLE),
1641                MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS),
1642                eq(false), eq(CAMERA_NOT_DISABLED));
1643        reset(mContext.userManagerInternal);
1644
1645        DpmTestUtils.assertRestrictions(
1646                DpmTestUtils.newRestrictions(
1647                        UserManager.DISALLOW_OUTGOING_CALLS
1648                ),
1649                dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE)
1650                        .ensureUserRestrictions()
1651        );
1652        DpmTestUtils.assertRestrictions(
1653                DpmTestUtils.newRestrictions(
1654                        UserManager.DISALLOW_OUTGOING_CALLS
1655                ),
1656                dpm.getUserRestrictions(admin1)
1657        );
1658
1659        dpm.clearUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS);
1660        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1661                eq(DpmMockContext.CALLER_USER_HANDLE),
1662                MockUtils.checkUserRestrictions(),
1663                eq(false), eq(CAMERA_NOT_DISABLED));
1664        reset(mContext.userManagerInternal);
1665
1666        DpmTestUtils.assertRestrictions(
1667                DpmTestUtils.newRestrictions(),
1668                dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE)
1669                        .ensureUserRestrictions()
1670        );
1671        DpmTestUtils.assertRestrictions(
1672                DpmTestUtils.newRestrictions(),
1673                dpm.getUserRestrictions(admin1)
1674        );
1675
1676        // DISALLOW_ADJUST_VOLUME and DISALLOW_UNMUTE_MICROPHONE can be set by PO too, even
1677        // though when DO sets them they'll be applied globally.
1678        dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADJUST_VOLUME);
1679        reset(mContext.userManagerInternal);
1680        dpm.addUserRestriction(admin1, UserManager.DISALLOW_UNMUTE_MICROPHONE);
1681        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1682                eq(DpmMockContext.CALLER_USER_HANDLE),
1683                MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADJUST_VOLUME,
1684                        UserManager.DISALLOW_UNMUTE_MICROPHONE),
1685                eq(false), eq(CAMERA_NOT_DISABLED));
1686        reset(mContext.userManagerInternal);
1687
1688        dpm.setCameraDisabled(admin1, true);
1689        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1690                eq(DpmMockContext.CALLER_USER_HANDLE),
1691                MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADJUST_VOLUME,
1692                        UserManager.DISALLOW_UNMUTE_MICROPHONE),
1693                eq(false), eq(CAMERA_DISABLED_LOCALLY));
1694        reset(mContext.userManagerInternal);
1695
1696        // TODO Make sure restrictions are written to the file.
1697    }
1698
1699
1700    public void testDefaultEnabledUserRestrictions() throws Exception {
1701        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
1702        mContext.callerPermissions.add(permission.MANAGE_USERS);
1703        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
1704        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
1705
1706        // First, set DO.
1707
1708        // Call from a process on the system user.
1709        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
1710
1711        // Make sure admin1 is installed on system user.
1712        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
1713
1714        dpm.setActiveAdmin(admin1, /* replace =*/ false, UserHandle.USER_SYSTEM);
1715        assertTrue(dpm.setDeviceOwner(admin1, "owner-name",
1716                UserHandle.USER_SYSTEM));
1717
1718        // Check that the user restrictions that are enabled by default are set. Then unset them.
1719        String[] defaultRestrictions = UserRestrictionsUtils
1720                .getDefaultEnabledForDeviceOwner().toArray(new String[0]);
1721        assertTrue(defaultRestrictions.length > 0);
1722        DpmTestUtils.assertRestrictions(
1723                DpmTestUtils.newRestrictions(defaultRestrictions),
1724                dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions()
1725        );
1726        DpmTestUtils.assertRestrictions(
1727                DpmTestUtils.newRestrictions(defaultRestrictions),
1728                dpm.getUserRestrictions(admin1)
1729        );
1730        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1731                eq(UserHandle.USER_SYSTEM),
1732                MockUtils.checkUserRestrictions(defaultRestrictions),
1733                eq(true) /* isDeviceOwner */,
1734                eq(CAMERA_NOT_DISABLED)
1735        );
1736        reset(mContext.userManagerInternal);
1737
1738        for (String restriction : defaultRestrictions) {
1739            dpm.clearUserRestriction(admin1, restriction);
1740        }
1741
1742        assertNoDeviceOwnerRestrictions();
1743
1744        // Initialize DPMS again and check that the user restriction wasn't enabled again.
1745        reset(mContext.userManagerInternal);
1746        initializeDpms();
1747        assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName()));
1748        assertNotNull(dpms.getDeviceOwnerAdminLocked());
1749
1750        assertNoDeviceOwnerRestrictions();
1751
1752        // Add a new restriction to the default set, initialize DPMS, and check that the restriction
1753        // is set as it wasn't enabled during setDeviceOwner.
1754        final String newDefaultEnabledRestriction = UserManager.DISALLOW_REMOVE_MANAGED_PROFILE;
1755        assertFalse(UserRestrictionsUtils
1756                .getDefaultEnabledForDeviceOwner().contains(newDefaultEnabledRestriction));
1757        UserRestrictionsUtils
1758                .getDefaultEnabledForDeviceOwner().add(newDefaultEnabledRestriction);
1759        try {
1760            reset(mContext.userManagerInternal);
1761            initializeDpms();
1762            assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName()));
1763            assertNotNull(dpms.getDeviceOwnerAdminLocked());
1764
1765            DpmTestUtils.assertRestrictions(
1766                DpmTestUtils.newRestrictions(newDefaultEnabledRestriction),
1767                dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions()
1768            );
1769            DpmTestUtils.assertRestrictions(
1770                DpmTestUtils.newRestrictions(newDefaultEnabledRestriction),
1771                dpm.getUserRestrictions(admin1)
1772            );
1773            verify(mContext.userManagerInternal, atLeast(1)).setDevicePolicyUserRestrictions(
1774                eq(UserHandle.USER_SYSTEM),
1775                MockUtils.checkUserRestrictions(newDefaultEnabledRestriction),
1776                eq(true) /* isDeviceOwner */,
1777                eq(CAMERA_NOT_DISABLED)
1778            );
1779            reset(mContext.userManagerInternal);
1780
1781            // Remove the restriction.
1782            dpm.clearUserRestriction(admin1, newDefaultEnabledRestriction);
1783
1784            // Initialize DPMS again. The restriction shouldn't be enabled for a second time.
1785            initializeDpms();
1786            assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName()));
1787            assertNotNull(dpms.getDeviceOwnerAdminLocked());
1788            assertNoDeviceOwnerRestrictions();
1789        } finally {
1790            UserRestrictionsUtils
1791                .getDefaultEnabledForDeviceOwner().remove(newDefaultEnabledRestriction);
1792        }
1793    }
1794
1795    private void assertNoDeviceOwnerRestrictions() {
1796        DpmTestUtils.assertRestrictions(
1797                DpmTestUtils.newRestrictions(),
1798                dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions()
1799        );
1800        DpmTestUtils.assertRestrictions(
1801                DpmTestUtils.newRestrictions(),
1802                dpm.getUserRestrictions(admin1)
1803        );
1804    }
1805
1806    public void testGetMacAddress() throws Exception {
1807        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
1808        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
1809        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
1810
1811        // In this test, change the caller user to "system".
1812        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
1813
1814        // Make sure admin1 is installed on system user.
1815        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
1816
1817        // Test 1. Caller doesn't have DO or DA.
1818        try {
1819            dpm.getWifiMacAddress(admin1);
1820            fail();
1821        } catch (SecurityException e) {
1822            MoreAsserts.assertContainsRegex("No active admin", e.getMessage());
1823        }
1824
1825        // DO needs to be an DA.
1826        dpm.setActiveAdmin(admin1, /* replace =*/ false);
1827        assertTrue(dpm.isAdminActive(admin1));
1828
1829        // Test 2. Caller has DA, but not DO.
1830        try {
1831            dpm.getWifiMacAddress(admin1);
1832            fail();
1833        } catch (SecurityException e) {
1834            MoreAsserts.assertContainsRegex("does not own the device", e.getMessage());
1835        }
1836
1837        // Test 3. Caller has PO, but not DO.
1838        assertTrue(dpm.setProfileOwner(admin1, null, UserHandle.USER_SYSTEM));
1839        try {
1840            dpm.getWifiMacAddress(admin1);
1841            fail();
1842        } catch (SecurityException e) {
1843            MoreAsserts.assertContainsRegex("does not own the device", e.getMessage());
1844        }
1845
1846        // Remove PO.
1847        dpm.clearProfileOwner(admin1);
1848        dpm.setActiveAdmin(admin1, false);
1849        // Test 4, Caller is DO now.
1850        assertTrue(dpm.setDeviceOwner(admin1, null, UserHandle.USER_SYSTEM));
1851
1852        // 4-1.  But no WifiInfo.
1853        assertNull(dpm.getWifiMacAddress(admin1));
1854
1855        // 4-2.  Returns WifiInfo, but with the default MAC.
1856        when(mContext.wifiManager.getConnectionInfo()).thenReturn(new WifiInfo());
1857        assertNull(dpm.getWifiMacAddress(admin1));
1858
1859        // 4-3. With a real MAC address.
1860        final WifiInfo wi = new WifiInfo();
1861        wi.setMacAddress("11:22:33:44:55:66");
1862        when(mContext.wifiManager.getConnectionInfo()).thenReturn(wi);
1863        assertEquals("11:22:33:44:55:66", dpm.getWifiMacAddress(admin1));
1864    }
1865
1866    public void testReboot() throws Exception {
1867        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
1868        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
1869
1870        // In this test, change the caller user to "system".
1871        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
1872
1873        // Make sure admin1 is installed on system user.
1874        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
1875
1876        // Set admin1 as DA.
1877        dpm.setActiveAdmin(admin1, false);
1878        assertTrue(dpm.isAdminActive(admin1));
1879        try {
1880            dpm.reboot(admin1);
1881            fail("DA calls DPM.reboot(), did not throw expected SecurityException");
1882        } catch (SecurityException expected) {
1883            MoreAsserts.assertContainsRegex("does not own the device", expected.getMessage());
1884        }
1885
1886        // Set admin1 as PO.
1887        assertTrue(dpm.setProfileOwner(admin1, null, UserHandle.USER_SYSTEM));
1888        try {
1889            dpm.reboot(admin1);
1890            fail("PO calls DPM.reboot(), did not throw expected SecurityException");
1891        } catch (SecurityException expected) {
1892            MoreAsserts.assertContainsRegex("does not own the device", expected.getMessage());
1893        }
1894
1895        // Remove PO and add DO.
1896        dpm.clearProfileOwner(admin1);
1897        dpm.setActiveAdmin(admin1, false);
1898        assertTrue(dpm.setDeviceOwner(admin1, null, UserHandle.USER_SYSTEM));
1899
1900        // admin1 is DO.
1901        // Set current call state of device to ringing.
1902        when(mContext.telephonyManager.getCallState())
1903                .thenReturn(TelephonyManager.CALL_STATE_RINGING);
1904        try {
1905            dpm.reboot(admin1);
1906            fail("DPM.reboot() called when receiveing a call, should thrown IllegalStateException");
1907        } catch (IllegalStateException expected) {
1908            MoreAsserts.assertContainsRegex("ongoing call on the device", expected.getMessage());
1909        }
1910
1911        // Set current call state of device to dialing/active.
1912        when(mContext.telephonyManager.getCallState())
1913                .thenReturn(TelephonyManager.CALL_STATE_OFFHOOK);
1914        try {
1915            dpm.reboot(admin1);
1916            fail("DPM.reboot() called when dialing, should thrown IllegalStateException");
1917        } catch (IllegalStateException expected) {
1918            MoreAsserts.assertContainsRegex("ongoing call on the device", expected.getMessage());
1919        }
1920
1921        // Set current call state of device to idle.
1922        when(mContext.telephonyManager.getCallState()).thenReturn(TelephonyManager.CALL_STATE_IDLE);
1923        dpm.reboot(admin1);
1924    }
1925
1926    public void testSetGetSupportText() {
1927        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
1928        dpm.setActiveAdmin(admin1, true);
1929        dpm.setActiveAdmin(admin2, true);
1930        mContext.callerPermissions.remove(permission.MANAGE_DEVICE_ADMINS);
1931
1932        // Null default support messages.
1933        {
1934            assertNull(dpm.getLongSupportMessage(admin1));
1935            assertNull(dpm.getShortSupportMessage(admin1));
1936            mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
1937            assertNull(dpm.getShortSupportMessageForUser(admin1,
1938                    DpmMockContext.CALLER_USER_HANDLE));
1939            assertNull(dpm.getLongSupportMessageForUser(admin1,
1940                    DpmMockContext.CALLER_USER_HANDLE));
1941            mMockContext.binder.callingUid = DpmMockContext.CALLER_UID;
1942        }
1943
1944        // Only system can call the per user versions.
1945        {
1946            try {
1947                dpm.getShortSupportMessageForUser(admin1,
1948                        DpmMockContext.CALLER_USER_HANDLE);
1949                fail("Only system should be able to call getXXXForUser versions");
1950            } catch (SecurityException expected) {
1951                MoreAsserts.assertContainsRegex("message for user", expected.getMessage());
1952            }
1953            try {
1954                dpm.getLongSupportMessageForUser(admin1,
1955                        DpmMockContext.CALLER_USER_HANDLE);
1956                fail("Only system should be able to call getXXXForUser versions");
1957            } catch (SecurityException expected) {
1958                MoreAsserts.assertContainsRegex("message for user", expected.getMessage());
1959            }
1960        }
1961
1962        // Can't set message for admin in another uid.
1963        {
1964            mContext.binder.callingUid = DpmMockContext.CALLER_UID + 1;
1965            try {
1966                dpm.setShortSupportMessage(admin1, "Some text");
1967                fail("Admins should only be able to change their own support text.");
1968            } catch (SecurityException expected) {
1969                MoreAsserts.assertContainsRegex("is not owned by uid", expected.getMessage());
1970            }
1971            mContext.binder.callingUid = DpmMockContext.CALLER_UID;
1972        }
1973
1974        // Set/Get short returns what it sets and other admins text isn't changed.
1975        {
1976            final String supportText = "Some text to test with.";
1977            dpm.setShortSupportMessage(admin1, supportText);
1978            assertEquals(supportText, dpm.getShortSupportMessage(admin1));
1979            assertNull(dpm.getLongSupportMessage(admin1));
1980            assertNull(dpm.getShortSupportMessage(admin2));
1981
1982            mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
1983            assertEquals(supportText, dpm.getShortSupportMessageForUser(admin1,
1984                    DpmMockContext.CALLER_USER_HANDLE));
1985            assertNull(dpm.getShortSupportMessageForUser(admin2,
1986                    DpmMockContext.CALLER_USER_HANDLE));
1987            assertNull(dpm.getLongSupportMessageForUser(admin1,
1988                    DpmMockContext.CALLER_USER_HANDLE));
1989            mMockContext.binder.callingUid = DpmMockContext.CALLER_UID;
1990
1991            dpm.setShortSupportMessage(admin1, null);
1992            assertNull(dpm.getShortSupportMessage(admin1));
1993        }
1994
1995        // Set/Get long returns what it sets and other admins text isn't changed.
1996        {
1997            final String supportText = "Some text to test with.\nWith more text.";
1998            dpm.setLongSupportMessage(admin1, supportText);
1999            assertEquals(supportText, dpm.getLongSupportMessage(admin1));
2000            assertNull(dpm.getShortSupportMessage(admin1));
2001            assertNull(dpm.getLongSupportMessage(admin2));
2002
2003            mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
2004            assertEquals(supportText, dpm.getLongSupportMessageForUser(admin1,
2005                    DpmMockContext.CALLER_USER_HANDLE));
2006            assertNull(dpm.getLongSupportMessageForUser(admin2,
2007                    DpmMockContext.CALLER_USER_HANDLE));
2008            assertNull(dpm.getShortSupportMessageForUser(admin1,
2009                    DpmMockContext.CALLER_USER_HANDLE));
2010            mMockContext.binder.callingUid = DpmMockContext.CALLER_UID;
2011
2012            dpm.setLongSupportMessage(admin1, null);
2013            assertNull(dpm.getLongSupportMessage(admin1));
2014        }
2015    }
2016
2017    public void testCreateAdminSupportIntent() throws Exception {
2018        // Setup device owner.
2019        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
2020        setupDeviceOwner();
2021
2022        // Nonexisting permission returns null
2023        Intent intent = dpm.createAdminSupportIntent("disallow_nothing");
2024        assertNull(intent);
2025
2026        // Existing permission that is not set returns null
2027        intent = dpm.createAdminSupportIntent(UserManager.DISALLOW_ADJUST_VOLUME);
2028        assertNull(intent);
2029
2030        // Existing permission that is not set by device/profile owner returns null
2031        when(mContext.userManager.hasUserRestriction(
2032                eq(UserManager.DISALLOW_ADJUST_VOLUME),
2033                eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid))))
2034                .thenReturn(true);
2035        intent = dpm.createAdminSupportIntent(UserManager.DISALLOW_ADJUST_VOLUME);
2036        assertNull(intent);
2037
2038        // Permission that is set by device owner returns correct intent
2039        when(mContext.userManager.getUserRestrictionSource(
2040                eq(UserManager.DISALLOW_ADJUST_VOLUME),
2041                eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid))))
2042                .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
2043        intent = dpm.createAdminSupportIntent(UserManager.DISALLOW_ADJUST_VOLUME);
2044        assertNotNull(intent);
2045        assertEquals(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS, intent.getAction());
2046        assertEquals(UserHandle.getUserId(DpmMockContext.CALLER_SYSTEM_USER_UID),
2047                intent.getIntExtra(Intent.EXTRA_USER_ID, -1));
2048        assertEquals(admin1,
2049                (ComponentName) intent.getParcelableExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN));
2050        assertEquals(UserManager.DISALLOW_ADJUST_VOLUME,
2051                intent.getStringExtra(DevicePolicyManager.EXTRA_RESTRICTION));
2052
2053        // Try with POLICY_DISABLE_CAMERA and POLICY_DISABLE_SCREEN_CAPTURE, which are not
2054        // user restrictions
2055
2056        // Camera is not disabled
2057        intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_CAMERA);
2058        assertNull(intent);
2059
2060        // Camera is disabled
2061        dpm.setCameraDisabled(admin1, true);
2062        intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_CAMERA);
2063        assertNotNull(intent);
2064        assertEquals(DevicePolicyManager.POLICY_DISABLE_CAMERA,
2065                intent.getStringExtra(DevicePolicyManager.EXTRA_RESTRICTION));
2066
2067        // Screen capture is not disabled
2068        intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE);
2069        assertNull(intent);
2070
2071        // Screen capture is disabled
2072        dpm.setScreenCaptureDisabled(admin1, true);
2073        intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE);
2074        assertNotNull(intent);
2075        assertEquals(DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE,
2076                intent.getStringExtra(DevicePolicyManager.EXTRA_RESTRICTION));
2077
2078        // Same checks for different user
2079        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
2080        // Camera should be disabled by device owner
2081        intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_CAMERA);
2082        assertNotNull(intent);
2083        assertEquals(DevicePolicyManager.POLICY_DISABLE_CAMERA,
2084                intent.getStringExtra(DevicePolicyManager.EXTRA_RESTRICTION));
2085        assertEquals(UserHandle.getUserId(DpmMockContext.CALLER_SYSTEM_USER_UID),
2086                intent.getIntExtra(Intent.EXTRA_USER_ID, -1));
2087        // ScreenCapture should not be disabled by device owner
2088        intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE);
2089        assertNull(intent);
2090    }
2091
2092    /**
2093     * Test for:
2094     * {@link DevicePolicyManager#setAffiliationIds}
2095     * {@link DevicePolicyManager#getAffiliationIds}
2096     * {@link DevicePolicyManager#isAffiliatedUser}
2097     */
2098    public void testUserAffiliation() throws Exception {
2099        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
2100        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2101        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
2102
2103        // Check that the system user is unaffiliated.
2104        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
2105        assertFalse(dpm.isAffiliatedUser());
2106
2107        // Set a device owner on the system user. Check that the system user becomes affiliated.
2108        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
2109        dpm.setActiveAdmin(admin1, /* replace =*/ false);
2110        assertTrue(dpm.setDeviceOwner(admin1, "owner-name"));
2111        assertTrue(dpm.isAffiliatedUser());
2112        assertTrue(dpm.getAffiliationIds(admin1).isEmpty());
2113
2114        // Install a profile owner. Check that the test user is unaffiliated.
2115        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
2116        setAsProfileOwner(admin2);
2117        assertFalse(dpm.isAffiliatedUser());
2118        assertTrue(dpm.getAffiliationIds(admin2).isEmpty());
2119
2120        // Have the profile owner specify a set of affiliation ids. Check that the test user remains
2121        // unaffiliated.
2122        final List<String> userAffiliationIds = new ArrayList<>();
2123        userAffiliationIds.add("red");
2124        userAffiliationIds.add("green");
2125        userAffiliationIds.add("blue");
2126        dpm.setAffiliationIds(admin2, userAffiliationIds);
2127        MoreAsserts.assertContentsInAnyOrder(dpm.getAffiliationIds(admin2), "red", "green", "blue");
2128        assertFalse(dpm.isAffiliatedUser());
2129
2130        // Have the device owner specify a set of affiliation ids that do not intersect with those
2131        // specified by the profile owner. Check that the test user remains unaffiliated.
2132        final List<String> deviceAffiliationIds = new ArrayList<>();
2133        deviceAffiliationIds.add("cyan");
2134        deviceAffiliationIds.add("yellow");
2135        deviceAffiliationIds.add("magenta");
2136        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
2137        dpm.setAffiliationIds(admin1, deviceAffiliationIds);
2138        MoreAsserts.assertContentsInAnyOrder(
2139            dpm.getAffiliationIds(admin1), "cyan", "yellow", "magenta");
2140        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
2141        assertFalse(dpm.isAffiliatedUser());
2142
2143        // Have the profile owner specify a set of affiliation ids that intersect with those
2144        // specified by the device owner. Check that the test user becomes affiliated.
2145        userAffiliationIds.add("yellow");
2146        dpm.setAffiliationIds(admin2, userAffiliationIds);
2147        MoreAsserts.assertContentsInAnyOrder(
2148            dpm.getAffiliationIds(admin2), "red", "green", "blue", "yellow");
2149        assertTrue(dpm.isAffiliatedUser());
2150
2151        // Clear affiliation ids for the profile owner. The user becomes unaffiliated.
2152        dpm.setAffiliationIds(admin2, Collections.emptyList());
2153        assertTrue(dpm.getAffiliationIds(admin2).isEmpty());
2154        assertFalse(dpm.isAffiliatedUser());
2155
2156        // Set affiliation ids again, then clear PO to check that the user becomes unaffiliated
2157        dpm.setAffiliationIds(admin2, userAffiliationIds);
2158        assertTrue(dpm.isAffiliatedUser());
2159        dpm.clearProfileOwner(admin2);
2160        assertFalse(dpm.isAffiliatedUser());
2161
2162        // Check that the system user remains affiliated.
2163        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
2164        assertTrue(dpm.isAffiliatedUser());
2165
2166        // Clear the device owner - the user becomes unaffiliated.
2167        clearDeviceOwner();
2168        assertFalse(dpm.isAffiliatedUser());
2169    }
2170
2171    public void testGetUserProvisioningState_defaultResult() {
2172        assertEquals(DevicePolicyManager.STATE_USER_UNMANAGED, dpm.getUserProvisioningState());
2173    }
2174
2175    public void testSetUserProvisioningState_permission() throws Exception {
2176        setupProfileOwner();
2177        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2178
2179        exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
2180                DevicePolicyManager.STATE_USER_SETUP_FINALIZED);
2181    }
2182
2183    public void testSetUserProvisioningState_unprivileged() throws Exception {
2184        setupProfileOwner();
2185        try {
2186            dpm.setUserProvisioningState(DevicePolicyManager.STATE_USER_SETUP_FINALIZED,
2187                    DpmMockContext.CALLER_USER_HANDLE);
2188            fail("Expected SecurityException");
2189        } catch (SecurityException expected) {
2190        }
2191    }
2192
2193    public void testSetUserProvisioningState_noManagement() {
2194        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2195        try {
2196            dpm.setUserProvisioningState(DevicePolicyManager.STATE_USER_SETUP_FINALIZED,
2197                    DpmMockContext.CALLER_USER_HANDLE);
2198            fail("IllegalStateException expected");
2199        } catch (IllegalStateException e) {
2200            MoreAsserts.assertContainsRegex("change provisioning state unless a .* owner is set",
2201                    e.getMessage());
2202        }
2203        assertEquals(DevicePolicyManager.STATE_USER_UNMANAGED, dpm.getUserProvisioningState());
2204    }
2205
2206    public void testSetUserProvisioningState_deviceOwnerFromSetupWizard() throws Exception {
2207        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
2208        setupDeviceOwner();
2209        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2210
2211        exerciseUserProvisioningTransitions(UserHandle.USER_SYSTEM,
2212                DevicePolicyManager.STATE_USER_SETUP_COMPLETE,
2213                DevicePolicyManager.STATE_USER_SETUP_FINALIZED);
2214    }
2215
2216    public void testSetUserProvisioningState_deviceOwnerFromSetupWizardAlternative()
2217            throws Exception {
2218        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
2219        setupDeviceOwner();
2220        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2221
2222        exerciseUserProvisioningTransitions(UserHandle.USER_SYSTEM,
2223                DevicePolicyManager.STATE_USER_SETUP_INCOMPLETE,
2224                DevicePolicyManager.STATE_USER_SETUP_FINALIZED);
2225    }
2226
2227    public void testSetUserProvisioningState_deviceOwnerWithoutSetupWizard() throws Exception {
2228        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
2229        setupDeviceOwner();
2230        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2231
2232        exerciseUserProvisioningTransitions(UserHandle.USER_SYSTEM,
2233                DevicePolicyManager.STATE_USER_SETUP_FINALIZED);
2234    }
2235
2236    public void testSetUserProvisioningState_managedProfileFromSetupWizard_primaryUser()
2237            throws Exception {
2238        setupProfileOwner();
2239        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2240
2241        exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
2242                DevicePolicyManager.STATE_USER_PROFILE_COMPLETE,
2243                DevicePolicyManager.STATE_USER_UNMANAGED);
2244    }
2245
2246    public void testSetUserProvisioningState_managedProfileFromSetupWizard_managedProfile()
2247            throws Exception {
2248        setupProfileOwner();
2249        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2250
2251        exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
2252                DevicePolicyManager.STATE_USER_SETUP_COMPLETE,
2253                DevicePolicyManager.STATE_USER_SETUP_FINALIZED);
2254    }
2255
2256    public void testSetUserProvisioningState_managedProfileWithoutSetupWizard() throws Exception {
2257        setupProfileOwner();
2258        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2259
2260        exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
2261                DevicePolicyManager.STATE_USER_SETUP_FINALIZED);
2262    }
2263
2264    public void testSetUserProvisioningState_illegalTransitionOutOfFinalized1() throws Exception {
2265        setupProfileOwner();
2266        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2267
2268        try {
2269            exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
2270                    DevicePolicyManager.STATE_USER_SETUP_FINALIZED,
2271                    DevicePolicyManager.STATE_USER_UNMANAGED);
2272            fail("Expected IllegalStateException");
2273        } catch (IllegalStateException e) {
2274            MoreAsserts.assertContainsRegex("Cannot move to user provisioning state",
2275                    e.getMessage());
2276        }
2277    }
2278
2279    public void testSetUserProvisioningState_illegalTransitionToAnotherInProgressState()
2280            throws Exception {
2281        setupProfileOwner();
2282        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2283
2284        try {
2285            exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
2286                    DevicePolicyManager.STATE_USER_SETUP_INCOMPLETE,
2287                    DevicePolicyManager.STATE_USER_SETUP_COMPLETE);
2288            fail("Expected IllegalStateException");
2289        } catch (IllegalStateException e) {
2290            MoreAsserts.assertContainsRegex("Cannot move to user provisioning state",
2291                    e.getMessage());
2292        }
2293    }
2294
2295    private void exerciseUserProvisioningTransitions(int userId, int... states) {
2296        assertEquals(DevicePolicyManager.STATE_USER_UNMANAGED, dpm.getUserProvisioningState());
2297        for (int state : states) {
2298            dpm.setUserProvisioningState(state, userId);
2299            assertEquals(state, dpm.getUserProvisioningState());
2300        }
2301    }
2302
2303    private void setupProfileOwner() throws Exception {
2304        mContext.callerPermissions.addAll(OWNER_SETUP_PERMISSIONS);
2305
2306        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID);
2307        dpm.setActiveAdmin(admin1, false);
2308        assertTrue(dpm.setProfileOwner(admin1, null, DpmMockContext.CALLER_USER_HANDLE));
2309
2310        mContext.callerPermissions.removeAll(OWNER_SETUP_PERMISSIONS);
2311    }
2312
2313    private void setupDeviceOwner() throws Exception {
2314        mContext.callerPermissions.addAll(OWNER_SETUP_PERMISSIONS);
2315
2316        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
2317        dpm.setActiveAdmin(admin1, false);
2318        assertTrue(dpm.setDeviceOwner(admin1, null, UserHandle.USER_SYSTEM));
2319
2320        mContext.callerPermissions.removeAll(OWNER_SETUP_PERMISSIONS);
2321    }
2322
2323    public void testSetMaximumTimeToLock() {
2324        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
2325
2326        dpm.setActiveAdmin(admin1, /* replace =*/ false);
2327        dpm.setActiveAdmin(admin2, /* replace =*/ false);
2328
2329        reset(mMockContext.powerManagerInternal);
2330        reset(mMockContext.settings);
2331
2332        dpm.setMaximumTimeToLock(admin1, 0);
2333        verifyScreenTimeoutCall(null, false);
2334        reset(mMockContext.powerManagerInternal);
2335        reset(mMockContext.settings);
2336
2337        dpm.setMaximumTimeToLock(admin1, 1);
2338        verifyScreenTimeoutCall(1, true);
2339        reset(mMockContext.powerManagerInternal);
2340        reset(mMockContext.settings);
2341
2342        dpm.setMaximumTimeToLock(admin2, 10);
2343        verifyScreenTimeoutCall(null, false);
2344        reset(mMockContext.powerManagerInternal);
2345        reset(mMockContext.settings);
2346
2347        dpm.setMaximumTimeToLock(admin1, 5);
2348        verifyScreenTimeoutCall(5, true);
2349        reset(mMockContext.powerManagerInternal);
2350        reset(mMockContext.settings);
2351
2352        dpm.setMaximumTimeToLock(admin2, 4);
2353        verifyScreenTimeoutCall(4, true);
2354        reset(mMockContext.powerManagerInternal);
2355        reset(mMockContext.settings);
2356
2357        dpm.setMaximumTimeToLock(admin1, 0);
2358        reset(mMockContext.powerManagerInternal);
2359        reset(mMockContext.settings);
2360
2361        dpm.setMaximumTimeToLock(admin2, Integer.MAX_VALUE);
2362        verifyScreenTimeoutCall(Integer.MAX_VALUE, true);
2363        reset(mMockContext.powerManagerInternal);
2364        reset(mMockContext.settings);
2365
2366        dpm.setMaximumTimeToLock(admin2, Integer.MAX_VALUE + 1);
2367        verifyScreenTimeoutCall(Integer.MAX_VALUE, true);
2368        reset(mMockContext.powerManagerInternal);
2369        reset(mMockContext.settings);
2370
2371        dpm.setMaximumTimeToLock(admin2, 10);
2372        verifyScreenTimeoutCall(10, true);
2373        reset(mMockContext.powerManagerInternal);
2374        reset(mMockContext.settings);
2375
2376        // There's no restriction; shold be set to MAX.
2377        dpm.setMaximumTimeToLock(admin2, 0);
2378        verifyScreenTimeoutCall(Integer.MAX_VALUE, false);
2379    }
2380
2381    public void testSetRequiredStrongAuthTimeout_DeviceOwner() throws Exception {
2382        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
2383        setupDeviceOwner();
2384        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2385
2386        final long MINIMUM_STRONG_AUTH_TIMEOUT_MS = TimeUnit.HOURS.toMillis(1);
2387        final long ONE_MINUTE = TimeUnit.MINUTES.toMillis(1);
2388        final long MIN_PLUS_ONE_MINUTE = MINIMUM_STRONG_AUTH_TIMEOUT_MS + ONE_MINUTE;
2389        final long MAX_MINUS_ONE_MINUTE = DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS
2390                - ONE_MINUTE;
2391
2392        // verify that the minimum timeout cannot be modified on user builds (system property is
2393        // not being read)
2394        mContext.buildMock.isDebuggable = false;
2395
2396        dpm.setRequiredStrongAuthTimeout(admin1, MAX_MINUS_ONE_MINUTE);
2397        assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), MAX_MINUS_ONE_MINUTE);
2398        assertEquals(dpm.getRequiredStrongAuthTimeout(null), MAX_MINUS_ONE_MINUTE);
2399
2400        verify(mContext.systemProperties, never()).getLong(anyString(), anyLong());
2401
2402        // restore to the debuggable build state
2403        mContext.buildMock.isDebuggable = true;
2404
2405        // Always return the default (second arg) when getting system property for long type
2406        when(mContext.systemProperties.getLong(anyString(), anyLong())).thenAnswer(
2407                new Answer<Long>() {
2408                    @Override
2409                    public Long answer(InvocationOnMock invocation) throws Throwable {
2410                        return (Long) invocation.getArguments()[1];
2411                    }
2412                }
2413        );
2414
2415        // reset to default (0 means the admin is not participating, so default should be returned)
2416        dpm.setRequiredStrongAuthTimeout(admin1, 0);
2417
2418        // aggregation should be the default if unset by any admin
2419        assertEquals(dpm.getRequiredStrongAuthTimeout(null),
2420                DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS);
2421
2422        // admin not participating by default
2423        assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), 0);
2424
2425        //clamping from the top
2426        dpm.setRequiredStrongAuthTimeout(admin1,
2427                DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS + ONE_MINUTE);
2428        assertEquals(dpm.getRequiredStrongAuthTimeout(admin1),
2429                DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS);
2430        assertEquals(dpm.getRequiredStrongAuthTimeout(null),
2431                DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS);
2432
2433        // 0 means the admin is not participating, so default should be returned
2434        dpm.setRequiredStrongAuthTimeout(admin1, 0);
2435        assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), 0);
2436        assertEquals(dpm.getRequiredStrongAuthTimeout(null),
2437                DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS);
2438
2439        // clamping from the bottom
2440        dpm.setRequiredStrongAuthTimeout(admin1, MINIMUM_STRONG_AUTH_TIMEOUT_MS - ONE_MINUTE);
2441        assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), MINIMUM_STRONG_AUTH_TIMEOUT_MS);
2442        assertEquals(dpm.getRequiredStrongAuthTimeout(null), MINIMUM_STRONG_AUTH_TIMEOUT_MS);
2443
2444        // values within range
2445        dpm.setRequiredStrongAuthTimeout(admin1, MIN_PLUS_ONE_MINUTE);
2446        assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), MIN_PLUS_ONE_MINUTE);
2447        assertEquals(dpm.getRequiredStrongAuthTimeout(null), MIN_PLUS_ONE_MINUTE);
2448
2449        dpm.setRequiredStrongAuthTimeout(admin1, MAX_MINUS_ONE_MINUTE);
2450        assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), MAX_MINUS_ONE_MINUTE);
2451        assertEquals(dpm.getRequiredStrongAuthTimeout(null), MAX_MINUS_ONE_MINUTE);
2452
2453        // reset to default
2454        dpm.setRequiredStrongAuthTimeout(admin1, 0);
2455        assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), 0);
2456        assertEquals(dpm.getRequiredStrongAuthTimeout(null),
2457                DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS);
2458
2459        // negative value
2460        try {
2461            dpm.setRequiredStrongAuthTimeout(admin1, -ONE_MINUTE);
2462            fail("Didn't throw IllegalArgumentException");
2463        } catch (IllegalArgumentException iae) {
2464        }
2465    }
2466
2467    private void verifyScreenTimeoutCall(Integer expectedTimeout,
2468            boolean shouldStayOnWhilePluggedInBeCleared) {
2469        if (expectedTimeout == null) {
2470            verify(mMockContext.powerManagerInternal, times(0))
2471                    .setMaximumScreenOffTimeoutFromDeviceAdmin(anyInt());
2472        } else {
2473            verify(mMockContext.powerManagerInternal, times(1))
2474                    .setMaximumScreenOffTimeoutFromDeviceAdmin(eq(expectedTimeout));
2475        }
2476        // TODO Verify calls to settingsGlobalPutInt.  Tried but somehow mockito threw
2477        // UnfinishedVerificationException.
2478    }
2479
2480    private void setup_DeviceAdminFeatureOff() throws Exception {
2481        when(mContext.packageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN))
2482                .thenReturn(false);
2483        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
2484                .thenReturn(false);
2485        initializeDpms();
2486        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(false);
2487        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
2488                .thenReturn(true);
2489        setUserSetupCompleteForUser(false, UserHandle.USER_SYSTEM);
2490
2491        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
2492    }
2493
2494    public void testIsProvisioningAllowed_DeviceAdminFeatureOff() throws Exception {
2495        setup_DeviceAdminFeatureOff();
2496        mContext.packageName = admin1.getPackageName();
2497        setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid);
2498        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, false);
2499        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false);
2500        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2501                false);
2502        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, false);
2503    }
2504
2505    public void testCheckProvisioningPreCondition_DeviceAdminFeatureOff() throws Exception {
2506        setup_DeviceAdminFeatureOff();
2507        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2508        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE,
2509                DevicePolicyManager.CODE_DEVICE_ADMIN_NOT_SUPPORTED);
2510        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2511                DevicePolicyManager.CODE_DEVICE_ADMIN_NOT_SUPPORTED);
2512        assertCheckProvisioningPreCondition(
2513                DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2514                DevicePolicyManager.CODE_DEVICE_ADMIN_NOT_SUPPORTED);
2515        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER,
2516                DevicePolicyManager.CODE_DEVICE_ADMIN_NOT_SUPPORTED);
2517    }
2518
2519    private void setup_ManagedProfileFeatureOff() throws Exception {
2520        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
2521                .thenReturn(false);
2522        initializeDpms();
2523        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(false);
2524        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
2525                .thenReturn(true);
2526        setUserSetupCompleteForUser(false, UserHandle.USER_SYSTEM);
2527
2528        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
2529    }
2530
2531    public void testIsProvisioningAllowed_ManagedProfileFeatureOff() throws Exception {
2532        setup_ManagedProfileFeatureOff();
2533        mContext.packageName = admin1.getPackageName();
2534        setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid);
2535        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, true);
2536        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false);
2537        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2538                false);
2539        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, false);
2540
2541        // Test again when split user is on
2542        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
2543        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, true);
2544        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false);
2545        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2546                true);
2547        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, false);
2548    }
2549
2550    public void testCheckProvisioningPreCondition_ManagedProfileFeatureOff() throws Exception {
2551        setup_ManagedProfileFeatureOff();
2552        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2553        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE,
2554                DevicePolicyManager.CODE_OK);
2555        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2556                DevicePolicyManager.CODE_MANAGED_USERS_NOT_SUPPORTED);
2557        assertCheckProvisioningPreCondition(
2558                DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2559                DevicePolicyManager.CODE_NOT_SYSTEM_USER_SPLIT);
2560        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER,
2561                DevicePolicyManager.CODE_MANAGED_USERS_NOT_SUPPORTED);
2562
2563        // Test again when split user is on
2564        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
2565        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE,
2566                DevicePolicyManager.CODE_OK);
2567        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2568                DevicePolicyManager.CODE_MANAGED_USERS_NOT_SUPPORTED);
2569        assertCheckProvisioningPreCondition(
2570                DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2571                DevicePolicyManager.CODE_OK);
2572        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER,
2573                DevicePolicyManager.CODE_MANAGED_USERS_NOT_SUPPORTED);
2574    }
2575
2576    private void setup_nonSplitUser_firstBoot_primaryUser() throws Exception {
2577        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
2578                .thenReturn(true);
2579        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(false);
2580        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
2581                .thenReturn(true);
2582        setUserSetupCompleteForUser(false, UserHandle.USER_SYSTEM);
2583
2584        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
2585    }
2586
2587    public void testIsProvisioningAllowed_nonSplitUser_firstBoot_primaryUser() throws Exception {
2588        setup_nonSplitUser_firstBoot_primaryUser();
2589        mContext.packageName = admin1.getPackageName();
2590        setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid);
2591        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, true);
2592        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true);
2593        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2594                false /* because of non-split user */);
2595        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER,
2596                false /* because of non-split user */);
2597    }
2598
2599    public void testCheckProvisioningPreCondition_nonSplitUser_firstBoot_primaryUser()
2600            throws Exception {
2601        setup_nonSplitUser_firstBoot_primaryUser();
2602        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2603        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE,
2604                DevicePolicyManager.CODE_OK);
2605        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2606                DevicePolicyManager.CODE_OK);
2607        assertCheckProvisioningPreCondition(
2608                DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2609                DevicePolicyManager.CODE_NOT_SYSTEM_USER_SPLIT);
2610        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER,
2611                DevicePolicyManager.CODE_NOT_SYSTEM_USER_SPLIT);
2612    }
2613
2614    private void setup_nonSplitUser_afterDeviceSetup_primaryUser() throws Exception {
2615        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
2616                .thenReturn(true);
2617        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(false);
2618        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
2619                .thenReturn(true);
2620        setUserSetupCompleteForUser(true, UserHandle.USER_SYSTEM);
2621
2622        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
2623    }
2624
2625    private void setup_nonSplitUser_withDo_primaryUser() throws Exception {
2626        setDeviceOwner();
2627        setup_nonSplitUser_afterDeviceSetup_primaryUser();
2628        setUpPackageManagerForFakeAdmin(adminAnotherPackage, DpmMockContext.ANOTHER_UID, admin2);
2629    }
2630
2631    private void setup_nonSplitUser_withDo_primaryUser_ManagedProfile() throws Exception {
2632        setup_nonSplitUser_withDo_primaryUser();
2633        final int MANAGED_PROFILE_USER_ID = 18;
2634        final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 1308);
2635        addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
2636        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM,
2637                false /* we can't remove a managed profile */)).thenReturn(false);
2638        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM,
2639                true)).thenReturn(true);
2640    }
2641
2642    public void testIsProvisioningAllowed_nonSplitUser_afterDeviceSetup_primaryUser()
2643            throws Exception {
2644        setup_nonSplitUser_afterDeviceSetup_primaryUser();
2645        mContext.packageName = admin1.getPackageName();
2646        setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid);
2647        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE,
2648                false/* because of completed device setup */);
2649        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true);
2650        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2651                false/* because of non-split user */);
2652        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER,
2653                false/* because of non-split user */);
2654    }
2655
2656    public void testCheckProvisioningPreCondition_nonSplitUser_afterDeviceSetup_primaryUser()
2657            throws Exception {
2658        setup_nonSplitUser_afterDeviceSetup_primaryUser();
2659        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2660        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE,
2661                DevicePolicyManager.CODE_USER_SETUP_COMPLETED);
2662        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2663                DevicePolicyManager.CODE_OK);
2664        assertCheckProvisioningPreCondition(
2665                DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2666                DevicePolicyManager.CODE_NOT_SYSTEM_USER_SPLIT);
2667        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER,
2668                DevicePolicyManager.CODE_NOT_SYSTEM_USER_SPLIT);
2669    }
2670
2671    public void testProvisioning_nonSplitUser_withDo_primaryUser() throws Exception {
2672        setup_nonSplitUser_withDo_primaryUser();
2673        mContext.packageName = admin1.getPackageName();
2674        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2675
2676        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE,
2677                DevicePolicyManager.CODE_HAS_DEVICE_OWNER);
2678        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, false);
2679
2680        // COMP mode is allowed.
2681        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2682                DevicePolicyManager.CODE_OK);
2683        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true);
2684
2685        // And other DPCs can also provision a managed profile (DO + BYOD case).
2686        assertCheckProvisioningPreCondition(
2687                DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2688                DpmMockContext.ANOTHER_PACKAGE_NAME,
2689                DevicePolicyManager.CODE_OK);
2690        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true,
2691                DpmMockContext.ANOTHER_PACKAGE_NAME, DpmMockContext.ANOTHER_UID);
2692    }
2693
2694    public void testProvisioning_nonSplitUser_withDo_primaryUser_restrictedByDo() throws Exception {
2695        setup_nonSplitUser_withDo_primaryUser();
2696        mContext.packageName = admin1.getPackageName();
2697        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2698        // The DO should be allowed to initiate provisioning if it set the restriction itself, but
2699        // other packages should be forbidden.
2700        when(mContext.userManager.hasUserRestriction(
2701                eq(UserManager.DISALLOW_ADD_MANAGED_PROFILE),
2702                eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid))))
2703                .thenReturn(true);
2704        when(mContext.userManager.getUserRestrictionSource(
2705                eq(UserManager.DISALLOW_ADD_MANAGED_PROFILE),
2706                eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid))))
2707                .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
2708        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2709                DevicePolicyManager.CODE_OK);
2710        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true);
2711        assertCheckProvisioningPreCondition(
2712                DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2713                DpmMockContext.ANOTHER_PACKAGE_NAME,
2714                DevicePolicyManager.CODE_ADD_MANAGED_PROFILE_DISALLOWED);
2715        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false,
2716                DpmMockContext.ANOTHER_PACKAGE_NAME, DpmMockContext.ANOTHER_UID);
2717    }
2718
2719    public void testProvisioning_nonSplitUser_withDo_primaryUser_restrictedBySystem()
2720            throws Exception {
2721        setup_nonSplitUser_withDo_primaryUser();
2722        mContext.packageName = admin1.getPackageName();
2723        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2724        // The DO should not be allowed to initiate provisioning if the restriction is set by
2725        // another entity.
2726        when(mContext.userManager.hasUserRestriction(
2727                eq(UserManager.DISALLOW_ADD_MANAGED_PROFILE),
2728                eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid))))
2729                .thenReturn(true);
2730        when(mContext.userManager.getUserRestrictionSource(
2731                eq(UserManager.DISALLOW_ADD_MANAGED_PROFILE),
2732                eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid))))
2733                .thenReturn(UserManager.RESTRICTION_SOURCE_SYSTEM);
2734        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2735                DevicePolicyManager.CODE_ADD_MANAGED_PROFILE_DISALLOWED);
2736        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false);
2737
2738        assertCheckProvisioningPreCondition(
2739                DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2740                DpmMockContext.ANOTHER_PACKAGE_NAME,
2741                DevicePolicyManager.CODE_ADD_MANAGED_PROFILE_DISALLOWED);
2742        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false,
2743                DpmMockContext.ANOTHER_PACKAGE_NAME, DpmMockContext.ANOTHER_UID);
2744    }
2745
2746    public void testCheckProvisioningPreCondition_nonSplitUser_comp() throws Exception {
2747        setup_nonSplitUser_withDo_primaryUser_ManagedProfile();
2748        mContext.packageName = admin1.getPackageName();
2749        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2750
2751        // We can delete the managed profile to create a new one, so provisioning is allowed.
2752        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2753                DevicePolicyManager.CODE_OK);
2754        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true);
2755        assertCheckProvisioningPreCondition(
2756                DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2757                DpmMockContext.ANOTHER_PACKAGE_NAME,
2758                DevicePolicyManager.CODE_OK);
2759        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true,
2760                DpmMockContext.ANOTHER_PACKAGE_NAME, DpmMockContext.ANOTHER_UID);
2761    }
2762
2763    public void testCheckProvisioningPreCondition_nonSplitUser_comp_cannot_remove_profile()
2764            throws Exception {
2765        setup_nonSplitUser_withDo_primaryUser_ManagedProfile();
2766        mContext.packageName = admin1.getPackageName();
2767        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2768        when(mContext.userManager.hasUserRestriction(
2769                eq(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE),
2770                eq(UserHandle.SYSTEM)))
2771                .thenReturn(true);
2772        when(mContext.userManager.getUserRestrictionSource(
2773                eq(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE),
2774                eq(UserHandle.SYSTEM)))
2775                .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
2776
2777        // We can't remove the profile to create a new one.
2778        assertCheckProvisioningPreCondition(
2779                DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2780                DpmMockContext.ANOTHER_PACKAGE_NAME,
2781                DevicePolicyManager.CODE_CANNOT_ADD_MANAGED_PROFILE);
2782        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false,
2783                DpmMockContext.ANOTHER_PACKAGE_NAME, DpmMockContext.ANOTHER_UID);
2784
2785        // But the device owner can still do it because it has set the restriction itself.
2786        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2787                DevicePolicyManager.CODE_OK);
2788        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true);
2789    }
2790
2791    private void setup_splitUser_firstBoot_systemUser() throws Exception {
2792        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
2793                .thenReturn(true);
2794        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
2795        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
2796                .thenReturn(false);
2797        setUserSetupCompleteForUser(false, UserHandle.USER_SYSTEM);
2798
2799        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
2800    }
2801
2802    public void testIsProvisioningAllowed_splitUser_firstBoot_systemUser() throws Exception {
2803        setup_splitUser_firstBoot_systemUser();
2804        mContext.packageName = admin1.getPackageName();
2805        setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid);
2806        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, true);
2807        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2808                false /* because canAddMoreManagedProfiles returns false */);
2809        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2810                true);
2811        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER,
2812                false/* because calling uid is system user */);
2813    }
2814
2815    public void testCheckProvisioningPreCondition_splitUser_firstBoot_systemUser()
2816            throws Exception {
2817        setup_splitUser_firstBoot_systemUser();
2818        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2819        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE,
2820                DevicePolicyManager.CODE_OK);
2821        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2822                DevicePolicyManager.CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER);
2823        assertCheckProvisioningPreCondition(
2824                DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2825                DevicePolicyManager.CODE_OK);
2826        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER,
2827                DevicePolicyManager.CODE_SYSTEM_USER);
2828    }
2829
2830    private void setup_splitUser_afterDeviceSetup_systemUser() throws Exception {
2831        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
2832                .thenReturn(true);
2833        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
2834        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
2835                .thenReturn(false);
2836        setUserSetupCompleteForUser(true, UserHandle.USER_SYSTEM);
2837
2838        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
2839    }
2840
2841    public void testIsProvisioningAllowed_splitUser_afterDeviceSetup_systemUser() throws Exception {
2842        setup_splitUser_afterDeviceSetup_systemUser();
2843        mContext.packageName = admin1.getPackageName();
2844        setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid);
2845        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE,
2846                true/* it's undefined behavior. Can be changed into false in the future */);
2847        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2848                false /* because canAddMoreManagedProfiles returns false */);
2849        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2850                true/* it's undefined behavior. Can be changed into false in the future */);
2851        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER,
2852                false/* because calling uid is system user */);
2853    }
2854
2855    public void testCheckProvisioningPreCondition_splitUser_afterDeviceSetup_systemUser()
2856            throws Exception {
2857        setup_splitUser_afterDeviceSetup_systemUser();
2858        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2859        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE,
2860                DevicePolicyManager.CODE_OK);
2861        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2862                DevicePolicyManager.CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER);
2863        assertCheckProvisioningPreCondition(
2864                DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2865                DevicePolicyManager.CODE_OK);
2866        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER,
2867                DevicePolicyManager.CODE_SYSTEM_USER);
2868    }
2869
2870    private void setup_splitUser_firstBoot_primaryUser() throws Exception {
2871        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
2872                .thenReturn(true);
2873        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
2874        when(mContext.userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
2875                true)).thenReturn(true);
2876        setUserSetupCompleteForUser(false, DpmMockContext.CALLER_USER_HANDLE);
2877
2878        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
2879    }
2880
2881    public void testIsProvisioningAllowed_splitUser_firstBoot_primaryUser() throws Exception {
2882        setup_splitUser_firstBoot_primaryUser();
2883        mContext.packageName = admin1.getPackageName();
2884        setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid);
2885        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, true);
2886        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true);
2887        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2888                true);
2889        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, true);
2890    }
2891
2892    public void testCheckProvisioningPreCondition_splitUser_firstBoot_primaryUser()
2893            throws Exception {
2894        setup_splitUser_firstBoot_primaryUser();
2895        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2896        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE,
2897                DevicePolicyManager.CODE_OK);
2898        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2899                DevicePolicyManager.CODE_OK);
2900        assertCheckProvisioningPreCondition(
2901                DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2902                DevicePolicyManager.CODE_OK);
2903        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER,
2904                DevicePolicyManager.CODE_OK);
2905    }
2906
2907    private void setup_splitUser_afterDeviceSetup_primaryUser() throws Exception {
2908        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
2909                .thenReturn(true);
2910        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
2911        when(mContext.userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
2912                true)).thenReturn(true);
2913        setUserSetupCompleteForUser(true, DpmMockContext.CALLER_USER_HANDLE);
2914
2915        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
2916    }
2917
2918    public void testIsProvisioningAllowed_splitUser_afterDeviceSetup_primaryUser()
2919            throws Exception {
2920        setup_splitUser_afterDeviceSetup_primaryUser();
2921        mContext.packageName = admin1.getPackageName();
2922        setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid);
2923        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE,
2924                true/* it's undefined behavior. Can be changed into false in the future */);
2925        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true);
2926        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2927                true/* it's undefined behavior. Can be changed into false in the future */);
2928        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER,
2929                false/* because user setup completed */);
2930    }
2931
2932    public void testCheckProvisioningPreCondition_splitUser_afterDeviceSetup_primaryUser()
2933            throws Exception {
2934        setup_splitUser_afterDeviceSetup_primaryUser();
2935        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2936        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE,
2937                DevicePolicyManager.CODE_OK);
2938        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2939                DevicePolicyManager.CODE_OK);
2940        assertCheckProvisioningPreCondition(
2941                DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2942                DevicePolicyManager.CODE_OK);
2943        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER,
2944                DevicePolicyManager.CODE_USER_SETUP_COMPLETED);
2945    }
2946
2947    private void setup_provisionManagedProfileWithDeviceOwner_systemUser() throws Exception {
2948        setDeviceOwner();
2949
2950        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
2951                .thenReturn(true);
2952        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
2953        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
2954                .thenReturn(false);
2955        setUserSetupCompleteForUser(true, UserHandle.USER_SYSTEM);
2956
2957        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
2958    }
2959
2960    public void testIsProvisioningAllowed_provisionManagedProfileWithDeviceOwner_systemUser()
2961            throws Exception {
2962        setup_provisionManagedProfileWithDeviceOwner_systemUser();
2963        mContext.packageName = admin1.getPackageName();
2964        setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid);
2965        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2966                false /* can't provision managed profile on system user */);
2967    }
2968
2969    public void testCheckProvisioningPreCondition_provisionManagedProfileWithDeviceOwner_systemUser()
2970            throws Exception {
2971        setup_provisionManagedProfileWithDeviceOwner_systemUser();
2972        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2973        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2974                DevicePolicyManager.CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER);
2975    }
2976
2977    private void setup_provisionManagedProfileWithDeviceOwner_primaryUser() throws Exception {
2978        setDeviceOwner();
2979
2980        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
2981                .thenReturn(true);
2982        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
2983        when(mContext.userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
2984                true)).thenReturn(true);
2985        setUserSetupCompleteForUser(false, DpmMockContext.CALLER_USER_HANDLE);
2986
2987        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
2988    }
2989
2990    public void testIsProvisioningAllowed_provisionManagedProfileWithDeviceOwner_primaryUser()
2991            throws Exception {
2992        setup_provisionManagedProfileWithDeviceOwner_primaryUser();
2993        setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid);
2994        mContext.packageName = admin1.getPackageName();
2995        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true);
2996    }
2997
2998    public void testCheckProvisioningPreCondition_provisionManagedProfileWithDeviceOwner_primaryUser()
2999            throws Exception {
3000        setup_provisionManagedProfileWithDeviceOwner_primaryUser();
3001        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
3002
3003        // COMP mode is allowed.
3004        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
3005                DevicePolicyManager.CODE_OK);
3006    }
3007
3008    private void setup_provisionManagedProfileCantRemoveUser_primaryUser() throws Exception {
3009        setDeviceOwner();
3010
3011        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
3012                .thenReturn(true);
3013        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
3014        when(mContext.userManager.hasUserRestriction(
3015                eq(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE),
3016                eq(UserHandle.of(DpmMockContext.CALLER_USER_HANDLE))))
3017                .thenReturn(true);
3018        when(mContext.userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
3019                false /* we can't remove a managed profile */)).thenReturn(false);
3020        when(mContext.userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
3021                true)).thenReturn(true);
3022        setUserSetupCompleteForUser(false, DpmMockContext.CALLER_USER_HANDLE);
3023
3024        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
3025    }
3026
3027    public void testIsProvisioningAllowed_provisionManagedProfileCantRemoveUser_primaryUser()
3028            throws Exception {
3029        setup_provisionManagedProfileCantRemoveUser_primaryUser();
3030        mContext.packageName = admin1.getPackageName();
3031        setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid);
3032        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false);
3033    }
3034
3035    public void testCheckProvisioningPreCondition_provisionManagedProfileCantRemoveUser_primaryUser()
3036            throws Exception {
3037        setup_provisionManagedProfileCantRemoveUser_primaryUser();
3038        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
3039        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
3040                DevicePolicyManager.CODE_CANNOT_ADD_MANAGED_PROFILE);
3041    }
3042
3043    public void testCheckProvisioningPreCondition_permission() {
3044        // GIVEN the permission MANAGE_PROFILE_AND_DEVICE_OWNERS is not granted
3045        try {
3046            dpm.checkProvisioningPreCondition(
3047                    DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, "some.package");
3048            fail("Didn't throw SecurityException");
3049        } catch (SecurityException expected) {
3050        }
3051    }
3052
3053    public void testForceUpdateUserSetupComplete_permission() {
3054        // GIVEN the permission MANAGE_PROFILE_AND_DEVICE_OWNERS is not granted
3055        try {
3056            dpm.forceUpdateUserSetupComplete();
3057            fail("Didn't throw SecurityException");
3058        } catch (SecurityException expected) {
3059        }
3060    }
3061
3062    public void testForceUpdateUserSetupComplete_systemUser() {
3063        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
3064        // GIVEN calling from user 20
3065        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
3066        try {
3067            dpm.forceUpdateUserSetupComplete();
3068            fail("Didn't throw SecurityException");
3069        } catch (SecurityException expected) {
3070        }
3071    }
3072
3073    public void testForceUpdateUserSetupComplete_userbuild() {
3074        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
3075        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3076
3077        final int userId = UserHandle.USER_SYSTEM;
3078        // GIVEN userComplete is false in SettingsProvider
3079        setUserSetupCompleteForUser(false, userId);
3080
3081        // GIVEN userComplete is true in DPM
3082        DevicePolicyManagerService.DevicePolicyData userData =
3083                new DevicePolicyManagerService.DevicePolicyData(userId);
3084        userData.mUserSetupComplete = true;
3085        dpms.mUserData.put(UserHandle.USER_SYSTEM, userData);
3086
3087        // GIVEN it's user build
3088        mContext.buildMock.isDebuggable = false;
3089
3090        assertTrue(dpms.hasUserSetupCompleted());
3091
3092        dpm.forceUpdateUserSetupComplete();
3093
3094        // THEN the state in dpms is not changed
3095        assertTrue(dpms.hasUserSetupCompleted());
3096    }
3097
3098    public void testForceUpdateUserSetupComplete_userDebugbuild() {
3099        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
3100        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3101
3102        final int userId = UserHandle.USER_SYSTEM;
3103        // GIVEN userComplete is false in SettingsProvider
3104        setUserSetupCompleteForUser(false, userId);
3105
3106        // GIVEN userComplete is true in DPM
3107        DevicePolicyManagerService.DevicePolicyData userData =
3108                new DevicePolicyManagerService.DevicePolicyData(userId);
3109        userData.mUserSetupComplete = true;
3110        dpms.mUserData.put(UserHandle.USER_SYSTEM, userData);
3111
3112        // GIVEN it's userdebug build
3113        mContext.buildMock.isDebuggable = true;
3114
3115        assertTrue(dpms.hasUserSetupCompleted());
3116
3117        dpm.forceUpdateUserSetupComplete();
3118
3119        // THEN the state in dpms is not changed
3120        assertFalse(dpms.hasUserSetupCompleted());
3121    }
3122
3123    private void clearDeviceOwner() throws Exception {
3124        final long ident = mContext.binder.clearCallingIdentity();
3125        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3126        doReturn(DpmMockContext.CALLER_SYSTEM_USER_UID).when(mContext.packageManager)
3127                .getPackageUidAsUser(eq(admin1.getPackageName()), anyInt());
3128        dpm.clearDeviceOwnerApp(admin1.getPackageName());
3129        mContext.binder.restoreCallingIdentity(ident);
3130    }
3131
3132    public void testGetLastSecurityLogRetrievalTime() throws Exception {
3133        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3134        setupDeviceOwner();
3135
3136        // setUp() adds a secondary user for CALLER_USER_HANDLE. Remove it as otherwise the
3137        // feature is disabled because there are non-affiliated secondary users.
3138        mContext.removeUser(DpmMockContext.CALLER_USER_HANDLE);
3139        when(mContext.resources.getBoolean(R.bool.config_supportPreRebootSecurityLogs))
3140                .thenReturn(true);
3141
3142        // No logs were retrieved so far.
3143        assertEquals(-1, dpm.getLastSecurityLogRetrievalTime());
3144
3145        // Enabling logging should not change the timestamp.
3146        dpm.setSecurityLoggingEnabled(admin1, true);
3147        verify(mContext.settings)
3148                .securityLogSetLoggingEnabledProperty(true);
3149        when(mContext.settings.securityLogGetLoggingEnabledProperty())
3150                .thenReturn(true);
3151        assertEquals(-1, dpm.getLastSecurityLogRetrievalTime());
3152
3153        // Retrieving the logs should update the timestamp.
3154        final long beforeRetrieval = System.currentTimeMillis();
3155        dpm.retrieveSecurityLogs(admin1);
3156        final long firstSecurityLogRetrievalTime = dpm.getLastSecurityLogRetrievalTime();
3157        final long afterRetrieval = System.currentTimeMillis();
3158        assertTrue(firstSecurityLogRetrievalTime >= beforeRetrieval);
3159        assertTrue(firstSecurityLogRetrievalTime <= afterRetrieval);
3160
3161        // Retrieving the pre-boot logs should update the timestamp.
3162        Thread.sleep(2);
3163        dpm.retrievePreRebootSecurityLogs(admin1);
3164        final long secondSecurityLogRetrievalTime = dpm.getLastSecurityLogRetrievalTime();
3165        assertTrue(secondSecurityLogRetrievalTime > firstSecurityLogRetrievalTime);
3166
3167        // Checking the timestamp again should not change it.
3168        Thread.sleep(2);
3169        assertEquals(secondSecurityLogRetrievalTime, dpm.getLastSecurityLogRetrievalTime());
3170
3171        // Retrieving the logs again should update the timestamp.
3172        dpm.retrieveSecurityLogs(admin1);
3173        final long thirdSecurityLogRetrievalTime = dpm.getLastSecurityLogRetrievalTime();
3174        assertTrue(thirdSecurityLogRetrievalTime > secondSecurityLogRetrievalTime);
3175
3176        // Disabling logging should not change the timestamp.
3177        Thread.sleep(2);
3178        dpm.setSecurityLoggingEnabled(admin1, false);
3179        assertEquals(thirdSecurityLogRetrievalTime, dpm.getLastSecurityLogRetrievalTime());
3180
3181        // Restarting the DPMS should not lose the timestamp.
3182        initializeDpms();
3183        assertEquals(thirdSecurityLogRetrievalTime, dpm.getLastSecurityLogRetrievalTime());
3184
3185        // Any uid holding MANAGE_USERS permission can retrieve the timestamp.
3186        mContext.binder.callingUid = 1234567;
3187        mContext.callerPermissions.add(permission.MANAGE_USERS);
3188        assertEquals(thirdSecurityLogRetrievalTime, dpm.getLastSecurityLogRetrievalTime());
3189        mContext.callerPermissions.remove(permission.MANAGE_USERS);
3190
3191        // System can retrieve the timestamp.
3192        mContext.binder.clearCallingIdentity();
3193        assertEquals(thirdSecurityLogRetrievalTime, dpm.getLastSecurityLogRetrievalTime());
3194
3195        // Removing the device owner should clear the timestamp.
3196        clearDeviceOwner();
3197        assertEquals(-1, dpm.getLastSecurityLogRetrievalTime());
3198    }
3199
3200    public void testGetLastBugReportRequestTime() throws Exception {
3201        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3202        setupDeviceOwner();
3203
3204        mContext.packageName = admin1.getPackageName();
3205        mContext.applicationInfo = new ApplicationInfo();
3206        when(mContext.resources.getColor(eq(R.color.notification_action_list), anyObject()))
3207                .thenReturn(Color.WHITE);
3208        when(mContext.resources.getColor(eq(R.color.notification_material_background_color),
3209                anyObject())).thenReturn(Color.WHITE);
3210
3211        // setUp() adds a secondary user for CALLER_USER_HANDLE. Remove it as otherwise the
3212        // feature is disabled because there are non-affiliated secondary users.
3213        mContext.removeUser(DpmMockContext.CALLER_USER_HANDLE);
3214
3215        // No bug reports were requested so far.
3216        assertEquals(-1, dpm.getLastBugReportRequestTime());
3217
3218        // Requesting a bug report should update the timestamp.
3219        final long beforeRequest = System.currentTimeMillis();
3220        dpm.requestBugreport(admin1);
3221        final long bugReportRequestTime = dpm.getLastBugReportRequestTime();
3222        final long afterRequest = System.currentTimeMillis();
3223        assertTrue(bugReportRequestTime >= beforeRequest);
3224        assertTrue(bugReportRequestTime <= afterRequest);
3225
3226        // Checking the timestamp again should not change it.
3227        Thread.sleep(2);
3228        assertEquals(bugReportRequestTime, dpm.getLastBugReportRequestTime());
3229
3230        // Restarting the DPMS should not lose the timestamp.
3231        initializeDpms();
3232        assertEquals(bugReportRequestTime, dpm.getLastBugReportRequestTime());
3233
3234        // Any uid holding MANAGE_USERS permission can retrieve the timestamp.
3235        mContext.binder.callingUid = 1234567;
3236        mContext.callerPermissions.add(permission.MANAGE_USERS);
3237        assertEquals(bugReportRequestTime, dpm.getLastBugReportRequestTime());
3238        mContext.callerPermissions.remove(permission.MANAGE_USERS);
3239
3240        // System can retrieve the timestamp.
3241        mContext.binder.clearCallingIdentity();
3242        assertEquals(bugReportRequestTime, dpm.getLastBugReportRequestTime());
3243
3244        // Removing the device owner should clear the timestamp.
3245        clearDeviceOwner();
3246        assertEquals(-1, dpm.getLastBugReportRequestTime());
3247    }
3248
3249    public void testGetLastNetworkLogRetrievalTime() throws Exception {
3250        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3251        setupDeviceOwner();
3252        mContext.packageName = admin1.getPackageName();
3253        mContext.applicationInfo = new ApplicationInfo();
3254        when(mContext.resources.getColor(eq(R.color.notification_action_list), anyObject()))
3255                .thenReturn(Color.WHITE);
3256        when(mContext.resources.getColor(eq(R.color.notification_material_background_color),
3257                anyObject())).thenReturn(Color.WHITE);
3258
3259        // setUp() adds a secondary user for CALLER_USER_HANDLE. Remove it as otherwise the
3260        // feature is disabled because there are non-affiliated secondary users.
3261        mContext.removeUser(DpmMockContext.CALLER_USER_HANDLE);
3262        when(mContext.iipConnectivityMetrics.registerNetdEventCallback(anyObject()))
3263                .thenReturn(true);
3264
3265        // No logs were retrieved so far.
3266        assertEquals(-1, dpm.getLastNetworkLogRetrievalTime());
3267
3268        // Attempting to retrieve logs without enabling logging should not change the timestamp.
3269        dpm.retrieveNetworkLogs(admin1, 0 /* batchToken */);
3270        assertEquals(-1, dpm.getLastNetworkLogRetrievalTime());
3271
3272        // Enabling logging should not change the timestamp.
3273        dpm.setNetworkLoggingEnabled(admin1, true);
3274        assertEquals(-1, dpm.getLastNetworkLogRetrievalTime());
3275
3276        // Retrieving the logs should update the timestamp.
3277        final long beforeRetrieval = System.currentTimeMillis();
3278        dpm.retrieveNetworkLogs(admin1, 0 /* batchToken */);
3279        final long firstNetworkLogRetrievalTime = dpm.getLastNetworkLogRetrievalTime();
3280        final long afterRetrieval = System.currentTimeMillis();
3281        assertTrue(firstNetworkLogRetrievalTime >= beforeRetrieval);
3282        assertTrue(firstNetworkLogRetrievalTime <= afterRetrieval);
3283
3284        // Checking the timestamp again should not change it.
3285        Thread.sleep(2);
3286        assertEquals(firstNetworkLogRetrievalTime, dpm.getLastNetworkLogRetrievalTime());
3287
3288        // Retrieving the logs again should update the timestamp.
3289        dpm.retrieveNetworkLogs(admin1, 0 /* batchToken */);
3290        final long secondNetworkLogRetrievalTime = dpm.getLastNetworkLogRetrievalTime();
3291        assertTrue(secondNetworkLogRetrievalTime > firstNetworkLogRetrievalTime);
3292
3293        // Disabling logging should not change the timestamp.
3294        Thread.sleep(2);
3295        dpm.setNetworkLoggingEnabled(admin1, false);
3296        assertEquals(secondNetworkLogRetrievalTime, dpm.getLastNetworkLogRetrievalTime());
3297
3298        // Restarting the DPMS should not lose the timestamp.
3299        initializeDpms();
3300        assertEquals(secondNetworkLogRetrievalTime, dpm.getLastNetworkLogRetrievalTime());
3301
3302        // Any uid holding MANAGE_USERS permission can retrieve the timestamp.
3303        mContext.binder.callingUid = 1234567;
3304        mContext.callerPermissions.add(permission.MANAGE_USERS);
3305        assertEquals(secondNetworkLogRetrievalTime, dpm.getLastNetworkLogRetrievalTime());
3306        mContext.callerPermissions.remove(permission.MANAGE_USERS);
3307
3308        // System can retrieve the timestamp.
3309        mContext.binder.clearCallingIdentity();
3310        assertEquals(secondNetworkLogRetrievalTime, dpm.getLastNetworkLogRetrievalTime());
3311
3312        // Removing the device owner should clear the timestamp.
3313        clearDeviceOwner();
3314        assertEquals(-1, dpm.getLastNetworkLogRetrievalTime());
3315    }
3316
3317    public void testGetBindDeviceAdminTargetUsers() throws Exception {
3318        // Setup device owner.
3319        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3320        setupDeviceOwner();
3321
3322        // Only device owner is setup, the result list should be empty.
3323        List<UserHandle> targetUsers = dpm.getBindDeviceAdminTargetUsers(admin1);
3324        MoreAsserts.assertEmpty(targetUsers);
3325
3326        // Setup a managed profile managed by the same admin.
3327        final int MANAGED_PROFILE_USER_ID = 15;
3328        final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 20456);
3329        addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
3330
3331        // Add a secondary user, it should never talk with.
3332        final int ANOTHER_USER_ID = 36;
3333        mContext.addUser(ANOTHER_USER_ID, 0);
3334
3335        // Since the managed profile is not affiliated, they should not be allowed to talk to each
3336        // other.
3337        targetUsers = dpm.getBindDeviceAdminTargetUsers(admin1);
3338        MoreAsserts.assertEmpty(targetUsers);
3339
3340        mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
3341        targetUsers = dpm.getBindDeviceAdminTargetUsers(admin1);
3342        MoreAsserts.assertEmpty(targetUsers);
3343
3344        // Setting affiliation ids
3345        final List<String> userAffiliationIds = Arrays.asList("some.affiliation-id");
3346        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3347        dpm.setAffiliationIds(admin1, userAffiliationIds);
3348
3349        mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
3350        dpm.setAffiliationIds(admin1, userAffiliationIds);
3351
3352        // Calling from device owner admin, the result list should just contain the managed
3353        // profile user id.
3354        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3355        targetUsers = dpm.getBindDeviceAdminTargetUsers(admin1);
3356        MoreAsserts.assertContentsInAnyOrder(targetUsers, UserHandle.of(MANAGED_PROFILE_USER_ID));
3357
3358        // Calling from managed profile admin, the result list should just contain the system
3359        // user id.
3360        mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
3361        targetUsers = dpm.getBindDeviceAdminTargetUsers(admin1);
3362        MoreAsserts.assertContentsInAnyOrder(targetUsers, UserHandle.SYSTEM);
3363
3364        // Changing affiliation ids in one
3365        dpm.setAffiliationIds(admin1, Arrays.asList("some-different-affiliation-id"));
3366
3367        // Since the managed profile is not affiliated any more, they should not be allowed to talk
3368        // to each other.
3369        targetUsers = dpm.getBindDeviceAdminTargetUsers(admin1);
3370        MoreAsserts.assertEmpty(targetUsers);
3371
3372        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3373        targetUsers = dpm.getBindDeviceAdminTargetUsers(admin1);
3374        MoreAsserts.assertEmpty(targetUsers);
3375    }
3376
3377    public void testGetBindDeviceAdminTargetUsers_differentPackage() throws Exception {
3378        // Setup a device owner.
3379        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3380        setupDeviceOwner();
3381
3382        // Set up a managed profile managed by different package.
3383        final int MANAGED_PROFILE_USER_ID = 15;
3384        final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 20456);
3385        final ComponentName adminDifferentPackage =
3386                new ComponentName("another.package", "whatever.class");
3387        addManagedProfile(adminDifferentPackage, MANAGED_PROFILE_ADMIN_UID, admin2);
3388
3389        // Setting affiliation ids
3390        final List<String> userAffiliationIds = Arrays.asList("some-affiliation-id");
3391        dpm.setAffiliationIds(admin1, userAffiliationIds);
3392
3393        mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
3394        dpm.setAffiliationIds(adminDifferentPackage, userAffiliationIds);
3395
3396        // Calling from device owner admin, we should get zero bind device admin target users as
3397        // their packages are different.
3398        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3399        List<UserHandle> targetUsers = dpm.getBindDeviceAdminTargetUsers(admin1);
3400        MoreAsserts.assertEmpty(targetUsers);
3401
3402        // Calling from managed profile admin, we should still get zero target users for the same
3403        // reason.
3404        mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
3405        targetUsers = dpm.getBindDeviceAdminTargetUsers(adminDifferentPackage);
3406        MoreAsserts.assertEmpty(targetUsers);
3407    }
3408
3409    public void testLockTaskPackagesAllowedForAffiliatedUsers() throws Exception {
3410        // Setup a device owner.
3411        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3412        setupDeviceOwner();
3413        // Lock task packages are updated when loading user data.
3414        verify(mContext.iactivityManager)
3415                .updateLockTaskPackages(eq(UserHandle.USER_SYSTEM), eq(new String[0]));
3416
3417        // Set up a managed profile managed by different package (package name shouldn't matter)
3418        final int MANAGED_PROFILE_USER_ID = 15;
3419        final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 20456);
3420        final ComponentName adminDifferentPackage =
3421                new ComponentName("another.package", "whatever.class");
3422        addManagedProfile(adminDifferentPackage, MANAGED_PROFILE_ADMIN_UID, admin2);
3423        verify(mContext.iactivityManager)
3424                .updateLockTaskPackages(eq(MANAGED_PROFILE_USER_ID), eq(new String[0]));
3425
3426        // The DO can still set lock task packages
3427        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3428        final String[] doPackages = {"doPackage1", "doPackage2"};
3429        dpm.setLockTaskPackages(admin1, doPackages);
3430        MoreAsserts.assertEquals(doPackages, dpm.getLockTaskPackages(admin1));
3431        assertTrue(dpm.isLockTaskPermitted("doPackage1"));
3432        assertFalse(dpm.isLockTaskPermitted("anotherPackage"));
3433        verify(mContext.iactivityManager)
3434                .updateLockTaskPackages(eq(UserHandle.USER_SYSTEM), eq(doPackages));
3435
3436        // Managed profile is unaffiliated - shouldn't be able to setLockTaskPackages.
3437        mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
3438        final String[] poPackages = {"poPackage1", "poPackage2"};
3439        try {
3440            dpm.setLockTaskPackages(adminDifferentPackage, poPackages);
3441            fail("Didn't throw expected security exception.");
3442        } catch (SecurityException expected) {
3443        }
3444        try {
3445            dpm.getLockTaskPackages(adminDifferentPackage);
3446            fail("Didn't throw expected security exception.");
3447        } catch (SecurityException expected) {
3448        }
3449        assertFalse(dpm.isLockTaskPermitted("doPackage1"));
3450
3451        // Setting same affiliation ids
3452        final List<String> userAffiliationIds = Arrays.asList("some-affiliation-id");
3453        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3454        dpm.setAffiliationIds(admin1, userAffiliationIds);
3455
3456        mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
3457        dpm.setAffiliationIds(adminDifferentPackage, userAffiliationIds);
3458
3459        // Now the managed profile can set lock task packages.
3460        dpm.setLockTaskPackages(adminDifferentPackage, poPackages);
3461        MoreAsserts.assertEquals(poPackages, dpm.getLockTaskPackages(adminDifferentPackage));
3462        assertTrue(dpm.isLockTaskPermitted("poPackage1"));
3463        assertFalse(dpm.isLockTaskPermitted("doPackage2"));
3464        verify(mContext.iactivityManager)
3465                .updateLockTaskPackages(eq(MANAGED_PROFILE_USER_ID), eq(poPackages));
3466
3467        // Unaffiliate the profile, lock task mode no longer available on the profile.
3468        dpm.setAffiliationIds(adminDifferentPackage, Collections.<String>emptyList());
3469        assertFalse(dpm.isLockTaskPermitted("poPackage1"));
3470        // Lock task packages cleared when loading user data and when the user becomes unaffiliated.
3471        verify(mContext.iactivityManager, times(2))
3472                .updateLockTaskPackages(eq(MANAGED_PROFILE_USER_ID), eq(new String[0]));
3473
3474        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3475        assertTrue(dpm.isLockTaskPermitted("doPackage1"));
3476    }
3477
3478    public void testIsDeviceManaged() throws Exception {
3479        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3480        setupDeviceOwner();
3481
3482        // The device owner itself, any uid holding MANAGE_USERS permission and the system can
3483        // find out that the device has a device owner.
3484        assertTrue(dpm.isDeviceManaged());
3485        mContext.binder.callingUid = 1234567;
3486        mContext.callerPermissions.add(permission.MANAGE_USERS);
3487        assertTrue(dpm.isDeviceManaged());
3488        mContext.callerPermissions.remove(permission.MANAGE_USERS);
3489        mContext.binder.clearCallingIdentity();
3490        assertTrue(dpm.isDeviceManaged());
3491
3492        clearDeviceOwner();
3493
3494        // Any uid holding MANAGE_USERS permission and the system can find out that the device does
3495        // not have a device owner.
3496        mContext.binder.callingUid = 1234567;
3497        mContext.callerPermissions.add(permission.MANAGE_USERS);
3498        assertFalse(dpm.isDeviceManaged());
3499        mContext.callerPermissions.remove(permission.MANAGE_USERS);
3500        mContext.binder.clearCallingIdentity();
3501        assertFalse(dpm.isDeviceManaged());
3502    }
3503
3504    public void testDeviceOwnerOrganizationName() throws Exception {
3505        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3506        setupDeviceOwner();
3507
3508        dpm.setOrganizationName(admin1, "organization");
3509
3510        // Device owner can retrieve organization managing the device.
3511        assertEquals("organization", dpm.getDeviceOwnerOrganizationName());
3512
3513        // Any uid holding MANAGE_USERS permission can retrieve organization managing the device.
3514        mContext.binder.callingUid = 1234567;
3515        mContext.callerPermissions.add(permission.MANAGE_USERS);
3516        assertEquals("organization", dpm.getDeviceOwnerOrganizationName());
3517        mContext.callerPermissions.remove(permission.MANAGE_USERS);
3518
3519        // System can retrieve organization managing the device.
3520        mContext.binder.clearCallingIdentity();
3521        assertEquals("organization", dpm.getDeviceOwnerOrganizationName());
3522
3523        // Removing the device owner clears the organization managing the device.
3524        clearDeviceOwner();
3525        assertNull(dpm.getDeviceOwnerOrganizationName());
3526    }
3527
3528    public void testWipeDataManagedProfile() throws Exception {
3529        final int MANAGED_PROFILE_USER_ID = 15;
3530        final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 19436);
3531        addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
3532        mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
3533
3534        // Even if the caller is the managed profile, the current user is the user 0
3535        when(mContext.iactivityManager.getCurrentUser())
3536                .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0));
3537
3538        dpm.wipeData(0);
3539        verify(mContext.userManagerInternal).removeUserEvenWhenDisallowed(
3540                MANAGED_PROFILE_USER_ID);
3541    }
3542
3543    public void testWipeDataManagedProfileDisallowed() throws Exception {
3544        final int MANAGED_PROFILE_USER_ID = 15;
3545        final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 19436);
3546        addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
3547
3548        // Even if the caller is the managed profile, the current user is the user 0
3549        when(mContext.iactivityManager.getCurrentUser())
3550                .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0));
3551
3552        when(mContext.userManager.getUserRestrictionSource(
3553                UserManager.DISALLOW_REMOVE_MANAGED_PROFILE,
3554                UserHandle.of(MANAGED_PROFILE_USER_ID)))
3555                .thenReturn(UserManager.RESTRICTION_SOURCE_SYSTEM);
3556        mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
3557        try {
3558            // The PO is not allowed to remove the profile if the user restriction was set on the
3559            // profile by the system
3560            dpm.wipeData(0);
3561            fail("SecurityException not thrown");
3562        } catch (SecurityException expected) {
3563        }
3564    }
3565
3566    public void testWipeDataDeviceOwner() throws Exception {
3567        setDeviceOwner();
3568        when(mContext.userManager.getUserRestrictionSource(
3569                UserManager.DISALLOW_FACTORY_RESET,
3570                UserHandle.SYSTEM))
3571                .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
3572
3573        dpm.wipeData(0);
3574        verify(mContext.recoverySystem).rebootWipeUserData(
3575                /*shutdown=*/ eq(false), anyString(), /*force=*/ eq(true));
3576    }
3577
3578    public void testWipeDataDeviceOwnerDisallowed() throws Exception {
3579        setDeviceOwner();
3580        when(mContext.userManager.getUserRestrictionSource(
3581                UserManager.DISALLOW_FACTORY_RESET,
3582                UserHandle.SYSTEM))
3583                .thenReturn(UserManager.RESTRICTION_SOURCE_SYSTEM);
3584        try {
3585            // The DO is not allowed to wipe the device if the user restriction was set
3586            // by the system
3587            dpm.wipeData(0);
3588            fail("SecurityException not thrown");
3589        } catch (SecurityException expected) {
3590        }
3591    }
3592
3593    public void testMaximumFailedPasswordAttemptsReachedManagedProfile() throws Exception {
3594        final int MANAGED_PROFILE_USER_ID = 15;
3595        final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 19436);
3596        addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
3597
3598        // Even if the caller is the managed profile, the current user is the user 0
3599        when(mContext.iactivityManager.getCurrentUser())
3600                .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0));
3601
3602        when(mContext.userManager.getUserRestrictionSource(
3603                UserManager.DISALLOW_REMOVE_MANAGED_PROFILE,
3604                UserHandle.of(MANAGED_PROFILE_USER_ID)))
3605                .thenReturn(UserManager.RESTRICTION_SOURCE_PROFILE_OWNER);
3606
3607        mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
3608        dpm.setMaximumFailedPasswordsForWipe(admin1, 3);
3609
3610        mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
3611        mContext.callerPermissions.add(permission.BIND_DEVICE_ADMIN);
3612        // Failed password attempts on the parent user are taken into account, as there isn't a
3613        // separate work challenge.
3614        dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM);
3615        dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM);
3616        dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM);
3617
3618        // The profile should be wiped even if DISALLOW_REMOVE_MANAGED_PROFILE is enabled, because
3619        // both the user restriction and the policy were set by the PO.
3620        verify(mContext.userManagerInternal).removeUserEvenWhenDisallowed(
3621                MANAGED_PROFILE_USER_ID);
3622        verifyZeroInteractions(mContext.recoverySystem);
3623    }
3624
3625    public void testMaximumFailedPasswordAttemptsReachedManagedProfileDisallowed()
3626            throws Exception {
3627        final int MANAGED_PROFILE_USER_ID = 15;
3628        final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 19436);
3629        addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
3630
3631        // Even if the caller is the managed profile, the current user is the user 0
3632        when(mContext.iactivityManager.getCurrentUser())
3633                .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0));
3634
3635        when(mContext.userManager.getUserRestrictionSource(
3636                UserManager.DISALLOW_REMOVE_MANAGED_PROFILE,
3637                UserHandle.of(MANAGED_PROFILE_USER_ID)))
3638                .thenReturn(UserManager.RESTRICTION_SOURCE_SYSTEM);
3639
3640        mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
3641        dpm.setMaximumFailedPasswordsForWipe(admin1, 3);
3642
3643        mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
3644        mContext.callerPermissions.add(permission.BIND_DEVICE_ADMIN);
3645        // Failed password attempts on the parent user are taken into account, as there isn't a
3646        // separate work challenge.
3647        dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM);
3648        dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM);
3649        dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM);
3650
3651        // DISALLOW_REMOVE_MANAGED_PROFILE was set by the system, not the PO, so the profile is
3652        // not wiped.
3653        verify(mContext.userManagerInternal, never())
3654                .removeUserEvenWhenDisallowed(anyInt());
3655        verifyZeroInteractions(mContext.recoverySystem);
3656    }
3657
3658    public void testMaximumFailedPasswordAttemptsReachedDeviceOwner() throws Exception {
3659        setDeviceOwner();
3660        when(mContext.userManager.getUserRestrictionSource(
3661                UserManager.DISALLOW_FACTORY_RESET,
3662                UserHandle.SYSTEM))
3663                .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
3664
3665        dpm.setMaximumFailedPasswordsForWipe(admin1, 3);
3666
3667        mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
3668        mContext.callerPermissions.add(permission.BIND_DEVICE_ADMIN);
3669        dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM);
3670        dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM);
3671        dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM);
3672
3673        // The device should be wiped even if DISALLOW_FACTORY_RESET is enabled, because both the
3674        // user restriction and the policy were set by the DO.
3675        verify(mContext.recoverySystem).rebootWipeUserData(
3676                /*shutdown=*/ eq(false), anyString(), /*force=*/ eq(true));
3677    }
3678
3679    public void testMaximumFailedPasswordAttemptsReachedDeviceOwnerDisallowed() throws Exception {
3680        setDeviceOwner();
3681        when(mContext.userManager.getUserRestrictionSource(
3682                UserManager.DISALLOW_FACTORY_RESET,
3683                UserHandle.SYSTEM))
3684                .thenReturn(UserManager.RESTRICTION_SOURCE_SYSTEM);
3685
3686        dpm.setMaximumFailedPasswordsForWipe(admin1, 3);
3687
3688        mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
3689        mContext.callerPermissions.add(permission.BIND_DEVICE_ADMIN);
3690        dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM);
3691        dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM);
3692        dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM);
3693
3694        // DISALLOW_FACTORY_RESET was set by the system, not the DO, so the device is not wiped.
3695        verifyZeroInteractions(mContext.recoverySystem);
3696        verify(mContext.userManagerInternal, never())
3697                .removeUserEvenWhenDisallowed(anyInt());
3698    }
3699
3700    public void testGetPermissionGrantState() throws Exception {
3701        final String permission = "some.permission";
3702        final String app1 = "com.example.app1";
3703        final String app2 = "com.example.app2";
3704
3705        when(mContext.ipackageManager.checkPermission(eq(permission), eq(app1), anyInt()))
3706                .thenReturn(PackageManager.PERMISSION_GRANTED);
3707        doReturn(PackageManager.FLAG_PERMISSION_POLICY_FIXED).when(mContext.packageManager)
3708                .getPermissionFlags(permission, app1, UserHandle.SYSTEM);
3709        when(mContext.packageManager.getPermissionFlags(permission, app1,
3710                UserHandle.of(DpmMockContext.CALLER_USER_HANDLE)))
3711                .thenReturn(PackageManager.FLAG_PERMISSION_POLICY_FIXED);
3712        when(mContext.ipackageManager.checkPermission(eq(permission), eq(app2), anyInt()))
3713                .thenReturn(PackageManager.PERMISSION_DENIED);
3714        doReturn(0).when(mContext.packageManager).getPermissionFlags(permission, app2,
3715                UserHandle.SYSTEM);
3716        when(mContext.packageManager.getPermissionFlags(permission, app2,
3717                UserHandle.of(DpmMockContext.CALLER_USER_HANDLE))).thenReturn(0);
3718
3719        // System can retrieve permission grant state.
3720        mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
3721        mContext.packageName = "com.example.system";
3722        assertEquals(DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED,
3723                dpm.getPermissionGrantState(null, app1, permission));
3724        assertEquals(DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT,
3725                dpm.getPermissionGrantState(null, app2, permission));
3726
3727        // A regular app cannot retrieve permission grant state.
3728        mContext.binder.callingUid = setupPackageInPackageManager(app1, 1);
3729        mContext.packageName = app1;
3730        try {
3731            dpm.getPermissionGrantState(null, app1, permission);
3732            fail("Didn't throw SecurityException");
3733        } catch (SecurityException expected) {
3734        }
3735
3736        // Profile owner can retrieve permission grant state.
3737        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
3738        mContext.packageName = admin1.getPackageName();
3739        setAsProfileOwner(admin1);
3740        assertEquals(DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED,
3741                dpm.getPermissionGrantState(admin1, app1, permission));
3742        assertEquals(DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT,
3743                dpm.getPermissionGrantState(admin1, app2, permission));
3744    }
3745
3746    public void testResetPasswordWithToken() throws Exception {
3747        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3748        setupDeviceOwner();
3749        // test token validation
3750        try {
3751            dpm.setResetPasswordToken(admin1, new byte[31]);
3752            fail("should not have accepted tokens too short");
3753        } catch (IllegalArgumentException expected) {
3754        }
3755        // test adding a token
3756        final byte[] token = new byte[32];
3757        final long handle = 123456;
3758        final String password = "password";
3759        when(mContext.lockPatternUtils.addEscrowToken(eq(token), eq(UserHandle.USER_SYSTEM)))
3760            .thenReturn(handle);
3761        assertTrue(dpm.setResetPasswordToken(admin1, token));
3762
3763        // test password activation
3764        when(mContext.lockPatternUtils.isEscrowTokenActive(eq(handle), eq(UserHandle.USER_SYSTEM)))
3765            .thenReturn(true);
3766        assertTrue(dpm.isResetPasswordTokenActive(admin1));
3767
3768        // test reset password with token
3769        when(mContext.lockPatternUtils.setLockCredentialWithToken(eq(password),
3770                eq(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD), eq(handle), eq(token),
3771                eq(UserHandle.USER_SYSTEM)))
3772                .thenReturn(true);
3773        assertTrue(dpm.resetPasswordWithToken(admin1, password, token, 0));
3774
3775        // test removing a token
3776        when(mContext.lockPatternUtils.removeEscrowToken(eq(handle), eq(UserHandle.USER_SYSTEM)))
3777                .thenReturn(true);
3778        assertTrue(dpm.clearResetPasswordToken(admin1));
3779    }
3780
3781    public void testIsDefaultInputMethodSetByOwnerForDeviceOwner() throws Exception {
3782        final String defaultIme = Settings.Secure.DEFAULT_INPUT_METHOD;
3783        final Uri defaultImeUri = Settings.Secure.getUriFor(defaultIme);
3784        final UserHandle firstUser = UserHandle.SYSTEM;
3785        final UserHandle secondUser = UserHandle.of(DpmMockContext.CALLER_USER_HANDLE);
3786
3787        // Set up a Device Owner.
3788        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3789        setupDeviceOwner();
3790
3791        // First and second user set default IMEs manually.
3792        final long ident = mContext.binder.clearCallingIdentity();
3793        assertFalse(dpm.isDefaultInputMethodSetByOwner(firstUser));
3794        assertFalse(dpm.isDefaultInputMethodSetByOwner(secondUser));
3795        mContext.binder.restoreCallingIdentity(ident);
3796
3797        // Device Owner changes default IME for first user.
3798        when(mContext.settings.settingsSecureGetStringForUser(defaultIme, UserHandle.USER_SYSTEM))
3799                .thenReturn("ime1");
3800        dpm.setSecureSetting(admin1, defaultIme, "ime2");
3801        verify(mContext.settings).settingsSecurePutStringForUser(defaultIme, "ime2",
3802                UserHandle.USER_SYSTEM);
3803        reset(mContext.settings);
3804        dpms.notifyChangeToContentObserver(defaultImeUri, UserHandle.USER_SYSTEM);
3805        mContext.binder.clearCallingIdentity();
3806        assertTrue(dpm.isDefaultInputMethodSetByOwner(firstUser));
3807        assertFalse(dpm.isDefaultInputMethodSetByOwner(secondUser));
3808        mContext.binder.restoreCallingIdentity(ident);
3809
3810        // Second user changes default IME manually.
3811        dpms.notifyChangeToContentObserver(defaultImeUri, DpmMockContext.CALLER_USER_HANDLE);
3812        mContext.binder.clearCallingIdentity();
3813        assertTrue(dpm.isDefaultInputMethodSetByOwner(firstUser));
3814        assertFalse(dpm.isDefaultInputMethodSetByOwner(secondUser));
3815        mContext.binder.restoreCallingIdentity(ident);
3816
3817        // First user changes default IME manually.
3818        dpms.notifyChangeToContentObserver(defaultImeUri, UserHandle.USER_SYSTEM);
3819        mContext.binder.clearCallingIdentity();
3820        assertFalse(dpm.isDefaultInputMethodSetByOwner(firstUser));
3821        assertFalse(dpm.isDefaultInputMethodSetByOwner(secondUser));
3822        mContext.binder.restoreCallingIdentity(ident);
3823
3824        // Device Owner changes default IME for first user again.
3825        when(mContext.settings.settingsSecureGetStringForUser(defaultIme, UserHandle.USER_SYSTEM))
3826                .thenReturn("ime2");
3827        dpm.setSecureSetting(admin1, defaultIme, "ime3");
3828        verify(mContext.settings).settingsSecurePutStringForUser(defaultIme, "ime3",
3829                UserHandle.USER_SYSTEM);
3830        dpms.notifyChangeToContentObserver(defaultImeUri, UserHandle.USER_SYSTEM);
3831        mContext.binder.clearCallingIdentity();
3832        assertTrue(dpm.isDefaultInputMethodSetByOwner(firstUser));
3833        assertFalse(dpm.isDefaultInputMethodSetByOwner(secondUser));
3834
3835        // Restarting the DPMS should not lose information.
3836        initializeDpms();
3837        assertTrue(dpm.isDefaultInputMethodSetByOwner(firstUser));
3838        assertFalse(dpm.isDefaultInputMethodSetByOwner(secondUser));
3839        mContext.binder.restoreCallingIdentity(ident);
3840
3841        // Device Owner can find out whether it set the default IME itself.
3842        assertTrue(dpm.isDefaultInputMethodSetByOwner(firstUser));
3843
3844        // Removing the Device Owner should clear the information that it set the default IME.
3845        clearDeviceOwner();
3846        mContext.binder.clearCallingIdentity();
3847        assertFalse(dpm.isDefaultInputMethodSetByOwner(firstUser));
3848        assertFalse(dpm.isDefaultInputMethodSetByOwner(secondUser));
3849    }
3850
3851    public void testIsDefaultInputMethodSetByOwnerForProfileOwner() throws Exception {
3852        final String defaultIme = Settings.Secure.DEFAULT_INPUT_METHOD;
3853        final Uri defaultImeUri = Settings.Secure.getUriFor(defaultIme);
3854        final UserHandle firstUser = UserHandle.SYSTEM;
3855        final UserHandle secondUser = UserHandle.of(DpmMockContext.CALLER_USER_HANDLE);
3856
3857        // Set up a profile owner.
3858        setupProfileOwner();
3859
3860        // First and second user set default IMEs manually.
3861        final long ident = mContext.binder.clearCallingIdentity();
3862        assertFalse(dpm.isDefaultInputMethodSetByOwner(firstUser));
3863        assertFalse(dpm.isDefaultInputMethodSetByOwner(secondUser));
3864        mContext.binder.restoreCallingIdentity(ident);
3865
3866        // Profile Owner changes default IME for second user.
3867        when(mContext.settings.settingsSecureGetStringForUser(defaultIme,
3868                DpmMockContext.CALLER_USER_HANDLE)).thenReturn("ime1");
3869        dpm.setSecureSetting(admin1, defaultIme, "ime2");
3870        verify(mContext.settings).settingsSecurePutStringForUser(defaultIme, "ime2",
3871                DpmMockContext.CALLER_USER_HANDLE);
3872        reset(mContext.settings);
3873        dpms.notifyChangeToContentObserver(defaultImeUri, DpmMockContext.CALLER_USER_HANDLE);
3874        mContext.binder.clearCallingIdentity();
3875        assertFalse(dpm.isDefaultInputMethodSetByOwner(firstUser));
3876        assertTrue(dpm.isDefaultInputMethodSetByOwner(secondUser));
3877        mContext.binder.restoreCallingIdentity(ident);
3878
3879        // First user changes default IME manually.
3880        dpms.notifyChangeToContentObserver(defaultImeUri, UserHandle.USER_SYSTEM);
3881        mContext.binder.clearCallingIdentity();
3882        assertFalse(dpm.isDefaultInputMethodSetByOwner(firstUser));
3883        assertTrue(dpm.isDefaultInputMethodSetByOwner(secondUser));
3884        mContext.binder.restoreCallingIdentity(ident);
3885
3886        // Second user changes default IME manually.
3887        dpms.notifyChangeToContentObserver(defaultImeUri, DpmMockContext.CALLER_USER_HANDLE);
3888        mContext.binder.clearCallingIdentity();
3889        assertFalse(dpm.isDefaultInputMethodSetByOwner(firstUser));
3890        assertFalse(dpm.isDefaultInputMethodSetByOwner(secondUser));
3891        mContext.binder.restoreCallingIdentity(ident);
3892
3893        // Profile Owner changes default IME for second user again.
3894        when(mContext.settings.settingsSecureGetStringForUser(defaultIme,
3895                DpmMockContext.CALLER_USER_HANDLE)).thenReturn("ime2");
3896        dpm.setSecureSetting(admin1, defaultIme, "ime3");
3897        verify(mContext.settings).settingsSecurePutStringForUser(defaultIme, "ime3",
3898                DpmMockContext.CALLER_USER_HANDLE);
3899        dpms.notifyChangeToContentObserver(defaultImeUri, DpmMockContext.CALLER_USER_HANDLE);
3900        mContext.binder.clearCallingIdentity();
3901        assertFalse(dpm.isDefaultInputMethodSetByOwner(firstUser));
3902        assertTrue(dpm.isDefaultInputMethodSetByOwner(secondUser));
3903
3904        // Restarting the DPMS should not lose information.
3905        initializeDpms();
3906        assertFalse(dpm.isDefaultInputMethodSetByOwner(firstUser));
3907        assertTrue(dpm.isDefaultInputMethodSetByOwner(secondUser));
3908        mContext.binder.restoreCallingIdentity(ident);
3909
3910        // Profile Owner can find out whether it set the default IME itself.
3911        assertTrue(dpm.isDefaultInputMethodSetByOwner(secondUser));
3912
3913        // Removing the Profile Owner should clear the information that it set the default IME.
3914        dpm.clearProfileOwner(admin1);
3915        mContext.binder.clearCallingIdentity();
3916        assertFalse(dpm.isDefaultInputMethodSetByOwner(firstUser));
3917        assertFalse(dpm.isDefaultInputMethodSetByOwner(secondUser));
3918    }
3919
3920    private void setUserSetupCompleteForUser(boolean isUserSetupComplete, int userhandle) {
3921        when(mContext.settings.settingsSecureGetIntForUser(Settings.Secure.USER_SETUP_COMPLETE, 0,
3922                userhandle)).thenReturn(isUserSetupComplete ? 1 : 0);
3923        dpms.notifyChangeToContentObserver(
3924                Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE), userhandle);
3925    }
3926
3927    private void assertProvisioningAllowed(String action, boolean expected) {
3928        assertEquals("isProvisioningAllowed(" + action + ") returning unexpected result", expected,
3929                dpm.isProvisioningAllowed(action));
3930    }
3931
3932    private void assertProvisioningAllowed(String action, boolean expected, String packageName,
3933            int uid) {
3934        String previousPackageName = mContext.packageName;
3935        int previousUid = mMockContext.binder.callingUid;
3936
3937        // Call assertProvisioningAllowed with the packageName / uid passed as arguments.
3938        mContext.packageName = packageName;
3939        mMockContext.binder.callingUid = uid;
3940        assertProvisioningAllowed(action, expected);
3941
3942        // Set the previous package name / calling uid to go back to the initial state.
3943        mContext.packageName = previousPackageName;
3944        mMockContext.binder.callingUid = previousUid;
3945    }
3946
3947    private void assertCheckProvisioningPreCondition(String action, int provisioningCondition) {
3948        assertCheckProvisioningPreCondition(action, admin1.getPackageName(), provisioningCondition);
3949    }
3950
3951    private void assertCheckProvisioningPreCondition(
3952            String action, String packageName, int provisioningCondition) {
3953        assertEquals("checkProvisioningPreCondition("
3954                        + action + ", " + packageName + ") returning unexpected result",
3955                provisioningCondition, dpm.checkProvisioningPreCondition(action, packageName));
3956    }
3957
3958    /**
3959     * Setup a managed profile with the specified admin and its uid.
3960     * @param admin ComponentName that's visible to the test code, which doesn't have to exist.
3961     * @param adminUid uid of the admin package.
3962     * @param copyFromAdmin package information for {@code admin} will be built based on this
3963     *     component's information.
3964     */
3965    private void addManagedProfile(
3966            ComponentName admin, int adminUid, ComponentName copyFromAdmin) throws Exception {
3967        final int userId = UserHandle.getUserId(adminUid);
3968        mContext.addUser(userId, UserInfo.FLAG_MANAGED_PROFILE, UserHandle.USER_SYSTEM);
3969        mContext.callerPermissions.addAll(OWNER_SETUP_PERMISSIONS);
3970        setUpPackageManagerForFakeAdmin(admin, adminUid, copyFromAdmin);
3971        dpm.setActiveAdmin(admin, false, userId);
3972        assertTrue(dpm.setProfileOwner(admin, null, userId));
3973        mContext.callerPermissions.removeAll(OWNER_SETUP_PERMISSIONS);
3974    }
3975
3976    /**
3977     * Convert String[] to ParceledListSlice&lt;ParcelableString&gt;.
3978     * <p>
3979     * TODO: This shouldn't be necessary. If ParcelableString does need to exist, it also needs
3980     * a real constructor.
3981     */
3982    private static ParceledListSlice<ParcelableString> asSlice(String[] s) {
3983        List<ParcelableString> list = new ArrayList<>(s.length);
3984        for (int i = 0; i < s.length; i++) {
3985            ParcelableString item = new ParcelableString();
3986            item.string = s[i];
3987            list.add(i, item);
3988        }
3989        return new ParceledListSlice<ParcelableString>(list);
3990    }
3991}
3992