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